import { ForeignToken } from "@daimo/contract"; import { Address, Hex } from "viem"; import { DaimoNoteStatus, DaimoRequestV2Status } from "./daimoLinkStatus"; import { BigIntStr } from "./model"; /** * A Clog (combined log) is an onchain event affecting a Daimo account. Each * Clog corresponds to an Ethereum event log. Usually--but not always--it is * also 1:1 with a Daimo userop. * * In the pending state, we don't have an event log yet--instead we have an * opHash &/or a txHash, and a future event log which we're expecting. * * Examples: * * - Sending from a Daimo account (Transfer log, userop) * - Receiving from elsewhere (Transfer log, may or may not be a userop) * - Registering a name (Register log, userop) * - Adding or removing a device (AddDevice / RemoveDevice log, userop) * - Creating or redeeming a Note (NoteCreated / NoteRedeemed log, userop) */ export type Clog = TransferClog | KeyRotationClog; export type TransferClog = TransferSwapClog | PaymentLinkClog; /** * Fetched data for a pending userop or sponsored transaction. Set exactly one * of (opHash, txHash) to uniquely identify a pending user action. */ export type PendingOp = { opHash?: Hex; txHash?: Hex; inviteCode?: string; }; /** * Original (non-home-coin) inbound transfer, for an inbound swap or inbound * cross-chain transfer. */ export type PreSwapTransfer = { coin: ForeignToken; amount: BigIntStr; from: Address; }; /** * Non-home-coin outbound transfer, for an outbound swap or outbound * cross-chain transfer. */ export type PostSwapTransfer = { coin: ForeignToken; amount: BigIntStr; to: Address; }; /** * Represents a transfer of the same tokens from one address to another on the * same chain (a.k.a. same coins, same chain). * * There's a surprising amount of complexity to the state of a transfer. * * - Daimo transfers start out as a `PENDING` user op. * The op goes through a lifecycle of pending (bundler has accepted, but not * yet onchain) to confirmed (bundle transaction onchain) to finalized * (written to a finalized L1 block, and therefore guaranteed permanent). * * For an optimistic rollup, a userop is arguably not finalized till the * challenge period is up; an L2 node can be 100% certain that a given op is * final after ~6 minutes (valid L2 root included in finalized L1 block) but * anyone not running an L2 full node has to wait a ~week to be sure. * * - A transfer ends up `CONFIRMED`/`FINALIZED` or `FAILED` if the op reverted. * * - A transfer can come from anywhere. Non-Daimo contracts or accounts * of any kind can send coins to a Daimo account. We learn about these *only* * from Transfer events--the userOpHash is null. * * - Daimo transfer, by contrast, will have a userOpHash, allowing us to track * them in the pending state. * * - For Daimo transfers, we show the username of the sender or recipient. * * - For others, we show an address, except for a few special ones where we can * show a descriptive slug like Daimo Faucet, Coinbase, or Binance. */ export interface TransferSwapClog extends ClogBase { type: "transfer"; from: Address; to: Address; /** TODO: use bigint? Unnecessary for USDC. MAX_SAFE_INT = $9,007,199,254 */ amount: number; /** Userop nonce, if this transfer occurred in a userop */ nonceMetadata?: Hex; /** Request metadata, if this transfer fulfilled a request */ requestStatus?: DaimoRequestV2Status; /** Memo, user-generated text for the transfer */ memo?: string; /** Original amount before swap to home coin */ preSwapTransfer?: PreSwapTransfer; /** Output amount after swap from home coin */ postSwapTransfer?: PostSwapTransfer; /** Remote transfer data associated with this transfer. e.g. Landline, Tron */ offchainTransfer?: OffchainTransfer; } export interface PaymentLinkClog extends ClogBase { type: "createLink" | "claimLink"; from: Address; to: Address; /** TODO: use bigint? Unnecessary for USDC. MAX_SAFE_INT = $9,007,199,254 */ amount: number; noteStatus: DaimoNoteStatus; /** Userop nonce, if this link occurred in a userop */ nonceMetadata?: Hex; /** Memo from the sender, if present */ memo?: string; } /** A transfer that happens offchain or on a non-Daimo chain (e.g. TRON). */ export interface OffchainTransfer { type: "landline"; transferType: "deposit" | "withdrawal"; status: "processing" | "completed" | "failed" | "returned"; statusMessage?: string; /** Remote account ID */ accountID: string; /** Remote transfer ID, if available */ transferID?: string; /** Unix seconds. Time the remote transfer was initiated */ timeStart: number; /** Unix seconds. Time the remote transfer was expected to complete */ timeExpected?: number; /** Unix seconds. Time the remote transfer was completed */ timeFinish?: number; } /** * Represents a token swap between two accounts on the same chain. * Same chain, different coins. * * A token swap can be inbound swap (e.g. a Daimo account receives a foreign * token transfer in their inbox) or outbound swap (e.g. account Alice sends a * foreign token transfer to Bob). */ export interface KeyRotationClog extends ClogBase { type: "keyRotation"; slot: number; rotationType: "add" | "remove"; } interface ClogBase { /** Unix seconds. When pending, bundler accept time. Otherwise, block time. */ timestamp: number; /** Eg, "pending", "confirmed", or "failed" */ status: OpStatus; opHash?: Hex; txHash?: Hex; blockNumber?: number; blockHash?: string; logIndex?: number; feeAmount?: number; } export declare enum OpStatus { /** Accepted by bundler &/or in mempool, but not yet onchain. */ pending = "pending", /** Succeeded onchain. */ confirmed = "confirmed", /** Succeeded onchain, & guaranteed via a finalized L1 block. */ finalized = "finalized", /** Failed onchain. */ failed = "failed", /** Pending too long, presumed dead. */ expired = "expired" } export type DaimoAccountCall = { dest: Address; value: bigint; data: Hex; }; export declare function getDisplayFromTo(op: TransferClog): [Address, Address]; export type TransferClogType = "transfer" | "createLink" | "claimLink" | "landline"; export declare function getTransferClogType(clog: TransferClog): TransferClogType; export type TransferClogStatus = "pending" | "processing" | "confirmed" | "finalized" | "failed" | "expired"; /** Returns a combined onchain + offchain transfer status. */ export declare function getTransferClogStatus(clog: TransferClog): TransferClogStatus; export {};