Payers are entities (typically app developers, agents, or service providers) who need to fund their accounts to pay for XMTP network services such as message broadcasting and identity updates. XMTP provides multiple funding mechanisms to accommodate different user preferences and technical capabilities.
The traditional manual funding process involves multiple steps across both XMTP Settlement and XMTP App Chains:
- Wallet setup: Create wallets on both the XMTP Settlement Chain (Base L2) and XMTP App Chain (XMTP L3)
- Token wrapping: Deposit USDC into the
FeeTokencontract, receivingxUSDtokens in exchange at a 1:1 ratio- This can be skipped if the payer uses the
Underlying-suffixed functions throughout the protocol.
- This can be skipped if the payer uses the
- XMTP Settlement Chain funding: Deposit
xUSDtokens into thePayerRegistryto cover costs for offchain message processing and settlement operations - XMTP App Chain funding: Transfer
xUSDtokens to the XMTP App Chain payer's wallet to cover gas costs for publishing blockchain messages and identity updates
For improved user experience, the DepositSplitter contract provides convenience functions that streamline the funding process:
deposit(): Allows payers to split deposits ofxUSDbetween thePayerRegistryandSettlementChainGateway(to be bridged to an XMTP App Chain) in a single transaction, assuming they have approved theDepositSplitterto spend theirxUSDtokens.depositWithPermit(): Allows payers to perform the above splitdeposit()without having to precede the transaction with an approval transaction.depositFromUnderlying(): Allows payers to deposit underlying fee tokens (i.e.,USDC) into thePayerRegistryandSettlementChainGateway(to be bridged to an XMTP App Chain) in a single transaction, assuming they have approved theDepositSplitterto spend their underlying fee tokens.depositFromUnderlyingWithPermit(): Allows payers to perform the above splitdepositFromUnderlying()without having to precede the transaction with an approval transaction.
This approach reduces the complexity from multiple transactions across different contracts to a single, atomic operation.
The XMTP Funding Portal provides a user-friendly interface that:
- Simplifies the funding process through an intuitive web interface
- Allows payers to connect their wallets directly using standard wallet connection protocols
- Abstracts away the technical complexity of cross-chain operations
- Provides real-time balance tracking across both XMTP Settlement and App Chains
The following diagram illustrates the complete process of a payer using the DepositSplitter contract to fund their accounts across both chains, sourced from USDC:
sequenceDiagram
title XMTP Payer Funding via DepositSplitter
participant Payer as Payer
participant USDC as USDC Token
participant DS as DepositSplitter
participant FT as FeeToken
participant PR as PayerRegistry
participant SCG as SettlementChainGateway
participant I as Inbox
Note over Payer: Phase 1: Setup and Approval
Payer->>USDC: approve(DepositSplitter, totalAmount)
activate USDC
USDC-->>Payer: Approval confirmed
deactivate USDC
Note over Payer: Phase 2: Deposit Splitting
Payer->>DS: deposit(address payer_, uint96 payerRegistryAmount_, address appChainRecipient_, uint96 appChainAmount_, uint256 appChainGasLimit_, uint256 appChainMaxFeePerGas_)
activate DS
Note over DS, FT: Step 1: Wrap USDC to xUSD
DS->>USDC: transferFrom(payer, DepositSplitter, totalAmount)
activate USDC
USDC-->>DS: Transfer successful
deactivate USDC
DS->>FT: deposit(totalAmount)
activate FT
FT->>FT: Mint xUSD tokens
FT-->>DS: xUSD tokens minted
deactivate FT
Note over DS, PR: Step 2: Fund PayerRegistry (Settlement Chain)
alt payerRegistryAmount > 0
DS->>PR: deposit(payer, payerRegistryAmount)
activate PR
PR->>FT: transferFrom(DepositSplitter, PayerRegistry, payerRegistryAmount)
activate FT
FT-->>PR: Transfer successful
deactivate FT
PR->>PR: Credit payer account
PR-->>DS: Deposit successful
deactivate PR
end
Note over DS, I: Step 3: Bridge to App Chain
alt appChainAmount > 0
DS->>SCG: deposit(appChainId, appChainRecipient, appChainAmount, gasLimit, maxFeePerGas)
activate SCG
SCG->>FT: transferFrom(DepositSplitter, SettlementChainGateway, appChainAmount)
activate FT
FT-->>SCG: Transfer successful
deactivate FT
SCG->>FT: approve(Inbox, appChainAmount)
activate FT
FT-->>SCG: Approval successful
deactivate FT
SCG->>I: Create retryable ticket (Cross-chain message)
I->>FT: transferFrom(SettlementChainGateway, Inbox, appChainAmount)
activate FT
FT-->>I: Transfer successful
deactivate FT
I->>SCG: Message Id
SCG->>DS: Deposit successful
end
DS-->>Payer: Deposit splitting completed
deactivate DS