Browser Tabs
A browser integration has two jobs: let the owner approve spending authority, then use a compatible session client to sign payments. Choose the approval and transaction-sponsorship path before wiring a payment button.
@dexterai/x402@6.0.0 supports context-bound V2 sessions and requires @dexterai/vault@0.43.4. A paid request also needs a reserveFinalVoucherV2 provider: an authenticated backend that confirms the exact signed reservation before the SDK releases the voucher. Keep the provider's authority and durable transaction handling on the server.
Use the Hosted Approval Flow
Dexter's hosted flow reviews the seller and the proposed limits, asks the owner for passkey approval, and handles registration sponsorship subject to eligibility checks. Your site keeps the agent's session secret on its own trusted runtime and supplies only the public key.
If you have a paid API URL, send the owner to /tabs/connect with the API's URL and the agent's session public key:
This helper uses @solana/web3.js@1. The resulting page reads the seller's x402 terms and lets the owner continue to approval. A URL that offers no tab produces a message instead of an approval request.
For your own cap, expiry, and callback, build a requestSpendGrant request and send it to /tabs/new?req=.... The Node grant guide includes a complete request generator and the callback contract. The URL-based lookup above does not configure a callback for your application.
Connect the Owner's Wallet
Follow Connect a Wallet with intent: 'wallet' and retain result.vault from the connection. That full Vault object supplies the owner's signer; registering a spending session still requires owner approval.
@dexterai/connect@0.29.1 exposes createPasskeySigner(vault). It creates the signer used for passkey-authorized Vault operations. Keep the connected account and authorization context current when asking the owner to sign.
Adapter Inputs
createSolanaVaultAdapter from @dexterai/x402/tab/adapters/solana takes these inputs in 6.0.0:
| Input | Required value |
|---|---|
connection | A Connection for reads and transaction submission. |
swigAddress | The Swig state account stored in vault.swig_address. The derived wallet address is a different account. |
vaultPda | The user's Dexter Vault account. |
passkeySigner | A PasskeySignerWithPublicKey for owner-authorized operations. |
feePayer | A funded Solana Signer, including its secret key, to pay transaction fees. |
The adapter's required Signer belongs to a self-paying integration. A shared sponsor secret must stay on your server; embedding it in browser JavaScript exposes it to every visitor. A newly generated browser keypair also needs SOL before it can pay fees. Hosted sponsorship uses its own server flow and cannot be enabled by supplying a public fee-payer address to this adapter.
Reserve Before Delivery
Pass reserveFinalVoucherV2 to openTab or payUrlWithTab alongside the Vault adapter. It receives the complete voucher and a stable idempotency key; forward that identity unchanged to your backend. Return its FinalVoucherV2ReservationReceipt after confirmation. The adapter independently checks the reservation transaction, voucher-binding Memo, and matching Vault/session state.
The SDK exposes this provider contract rather than a ready-made reservation endpoint. Configure it with the backend authorized for your Vault before enabling paid requests. The Node integration shows the grant constructor and voucher header; the same receipt must accompany browser requests.
Session Lifecycle
The published API expresses two limits as human USDC strings: perUnitCap limits one voucher increase, and totalCap limits the session's cumulative spend. sessionDuration is in seconds.
openTab asks the adapter to register a session. The owner may need additional passkey approval for wallet activation or replacement. onLiveSession: 'error' refuses to replace an existing session for the same Vault and seller. Keep that behavior unless your application has reconciled the old session's unsettled vouchers.
signNextVoucher(amountAtomic) signs and reserves the requested increment before returning it. stream(url) in 6.0.0 signs the full perUnitCap once before reading the SSE response. Streaming output does not trigger additional per-chunk voucher exchanges.
Browser close() attempts settlement and then passkey-authorized revocation. Check the result's sessionRevoked field and preserve any settlement signature. An unused tab can have an empty settleTx; a failed close needs reconciliation before another attempt. See Close and Revoke.
Integration Failures
| Symptom | Action |
|---|---|
| Existing session blocks approval | Inspect the old session and outstanding vouchers before replacing it. |
| Hosted registration is unavailable | Resolve the displayed eligibility or funding requirement before requesting approval again. |
| Adapter transaction lacks funds or a signer | Check the fee-payer transport; an owner passkey authorizes the operation but does not pay its SOL fee. |
| Voucher or reservation is rejected | Preserve the owner's grant values and include the full reservation receipt in the voucher header. Check the exact transaction and session state before retrying. |
| Settlement succeeded but revocation failed | Keep the settlement receipt and complete revocation with the owner; paying again would create another charge. |
Last Updated: