Skip to main content
The customer connects a wallet and signs one transaction: MerchantPool.deposit(paymentId, token, amount). Funds go straight into the pool. The platform touches nothing.

Properties

Because the platform fronts nothing, platformFloor(chainId, "connect") returns 0 on every chain. This makes the connect rail the correct destination for any payment too small to justify the deposit rail’s sponsored gas.

Flow

1

Quote

create-quote prices the order and returns the token amount. The pool address is derived and returned with a binding bundle the client re-proves.
2

Verify before signing

The widget reads MerchantRegistry.effectiveRecipient(anchor) on-chain, re-derives the pool address from that chain-read value, and cross-checks the deployed pool’s recipient(). Any mismatch produces a terminal pool_mismatch state and signing is blocked. See DB-display-only trust.
3

Approve and deposit

Standard ERC-20 approval followed by deposit(). On TRON this will be MerchantPoolTron.deposit() once the connect rail lands there.
4

Confirm

The indexer observes the Deposited event. Capture is at required confirmations — not first-seen.

Recipient race protection

Between quoting and signing, the on-chain recipient could change. The widget re-reads effectiveRecipient immediately before the signature. On mismatch it enters a recipient_changed state with a calm warning and a refresh action, and no signature is sent.

Wallet coverage

EVM coverage comes through Reown AppKit. AppKit’s built-in Swaps widget is disabled (swaps: false) because no aggregator may sit in the trust path. TRON is a separate stack. The WalletConnect-TRON connector ships via @tronweb3/walletconnect-tron, not a first-party Reown adapter. Verified over standard WC-TRON: TokenPocket, Trust Wallet, Binance Web3, SafePal. OKX requires its own OKX Connect protocol. Bitget is unverified. Injected TronLink remains a parallel path.

TRON status

TRON does not have a connect rail today. railEconomics.ts:availableRails() hard-returns ["deposit"] for TRON, making it the only chain where a customer cannot pay from a connected wallet.
GO was given 2026-08-05. The target is MerchantPoolTron.deposit() direct — explicitly not a WalletConnect-signed plain transfer to a forwarder, which would still require a keeper deploy and sweep and therefore save nothing. Most of the plumbing exists: MerchantPoolTron.deposit() is implemented and tron-pool-keeper already handles rail === "connect" and observes Deposited events. The gap is the widget. This matters more on TRON than anywhere else. Every deposit-rail optimisation still leaves a floor; only the connect rail removes it, because the customer’s own wallet pays the energy. The honest customer-side trade on TRON: approve plus deposit costs roughly 2.40versusabout2.40 versus about 1.40 for a plain transfer. TRON users already expect $1–3 per USDT transfer, so this is tolerable, and a consume_user_resource_percent spike may remove it entirely.