Payment links: the agent drafts, you sign
An agent can prepare a payment but never send one. The wallet_draft_payment tool takes a recipient, an amount in USDC or ETH, a chain (Base or Arbitrum), and an optional note, and returns a link. Opening the link shows the payment as a card: amount, network, recipient, note, expiry. Nothing has moved yet, and nothing can move until you act.
To pay, you sign in your own wallet. The page offers two buttons. "Pay with passkey" opens Coinbase Smart Wallet, where approving is a Face ID or fingerprint prompt: the key lives in your device's secure enclave and never leaves it. "Use browser wallet" hands the same transaction to MetaMask or whatever wallet your browser has installed. Either way, the transaction is built in your browser, shown by your wallet, and signed by you. The signing page never sees a key and has no way to submit anything on its own.
The link itself is signed too, for a different reason. Each draft carries a server signature, so a link that renders as a Daslab payment request can only have come from an agent in your world. A tampered or forged link gets an error page, not a payment card. Links also expire, after 24 hours by default, so a stale draft cannot resurface later.
Confirmation comes from the chain, not from us. After you sign, your wallet submits the transaction and the page links to it on the block explorer. The agent that drafted the payment sees it the same way anyone can: the transfer appears in wallet_token_transfers or wallet_transactions on the linked address. There is no Daslab ledger in the middle, and Daslab takes no fee on the payment.
The division of labor is the point. The agent does the tedious part: getting the recipient, amount, and chain right. You do the one part that matters, with the one thing only you have. Your keys stay yours.