EvmWallet, and the SDK drives it. Do that once and every on-chain flow works - Superstate swaps, Ondo buys, token-sale approvals, ownership proofs.
The SDK uses and ships viem types, the de-facto TypeScript standard for Ethereum, so the interface lines up with whatever you are already using. A
SolanaWallet seam will follow the same shape when Solana lands.Two shapes, one seam
There are two interfaces, and the smaller one is a subset of the larger.EvmWallet extends EvmSigner, so implementing the full interface satisfies both. If all you need is the requirements checklist binding a wallet to an offer option, EvmSigner is enough and your users never see a gas prompt.
Implement EvmWallet
Every method that takes a chain gets it as an explicit parameter. Switch the wallet to that chain before acting - the SDK does not assume your wallet is already pointed at the right one.
Adapter: wagmi and AppKit
This is the canonical adapter, and it is the one the partner demo runs. Any stack that can sign a message and send a transaction works the same way.wagmiEvmWallet.ts
Let wallet errors propagate
Do not catch and translate your wallet library’s errors. Let them throw. The SDK catches them and classifies them into a typedWalletError, so you never parse a wallet error string yourself:
Flows surface it as the
cause on the step that failed, so you can tell a user rejection apart from an infrastructure problem. See Errors and edge cases for the full breakdown.
Proving wallet ownership
Two identities are involved in every Passage purchase, and they are not the same thing:- The CoinList session (from OAuth) identifies who is investing.
- The wallet is where the assets are delivered.
coinlist.wallets also reads and removes those bindings: list({ offerId, offerOptionId }) returns the wallets bound to an option, and remove({ offerId, addressId }) unbinds one.
CheckoutWalletSelection: what checkout takes
EvmWallet is what the SDK drives. CheckoutWalletSelection is what you hand CheckoutContainer: the wallets the buyer may spend from, plus the two lambdas that connect and disconnect an external one.
EvmWallet already carries the address, so an { address, signer } pair would be a second wallet type to keep in sync with the first. Everything a wallet row displays beyond the address - the network name - comes from the checkout’s execution chain rather than from the wallet, because that is the chain the transaction goes to whatever the wallet is currently pointed at.
Next step
Building the Checkout flow
Hand your wallets to
CheckoutContainer and let it render whichever provider the offer belongs to.