Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
The 3-step signing pattern · Boson Protocol
Skip to content

The 3-step signing pattern

State-changing MCP tools never sign for you. They return an unsigned transaction; your code signs and broadcasts. This pattern keeps private keys out of the MCP server.

For the canonical signing reference (typed-data shapes, meta-tx variants), see Concepts → Signing & meta-transactions. This page is the agent-specific operational view.

The three steps

1. Prepare    — MCP tool returns { to, data, value, gasLimit, chainId }
2. Sign       — your wallet signs the raw tx
3. Broadcast  — send via send_signed_transaction (or your own RPC)
// 1. Prepare
const { unsignedTx } = await mcp.commitToOffer({
  configId: "production-137-0",
  signerAddress: wallet.address,
  buyer: wallet.address,
  offerId,
})
 
// 2. Sign
const signed = await wallet.signTransaction(unsignedTx)
 
// 3. Broadcast
const { txHash } = await mcp.sendSignedTransaction({
  chainId: 137,
  signedTx: signed,
})
 
// (optional 4) Wait for indexing before reading
await mcp.waitForIndexing({ configId: "production-137-0", blockNumber: receipt.blockNumber })

Meta-transaction variant

If you want a relayer to pay gas instead of the agent:

// 1. Sign the inner meta-tx envelope
const { signedMetaTx } = await mcp.signMetaTransaction({
  configId,
  functionName: "commitToOffer",
  functionArgs: { buyer, offerId },
  userAddress: wallet.address,
})
 
// 2. Submit through the relayer
await mcp.sendMetaTransaction(signedMetaTx)

Variants:

  • send_meta_transaction — Boson-generic, via Biconomy.
  • send_native_meta_transaction — direct on-chain EIP-712 (no relayer).
  • send_forwarded_meta_transaction — token-auth meta-tx (single sig covers approve + call).

Pick by your gas-economics and the buyer's UX. See Concepts → Signing.

Per-tool signing requirements

Tool categoryReturns unsigned?Signing required?
get_* (reads)n/aNo
create_seller, update_seller, create_buyerYesYes
create_offer, void_offer, …YesYes
commit_to_offer, redeem_voucher, cancel_voucher, …YesYes
raise_dispute, resolve_dispute, …YesYes
deposit_funds, withdraw_fundsYesYes
sign_full_offerReturns a signed FullOffer (server signs the typed-data structure)No, but you must trust the server
validate_metadata, render_contractual_agreementn/aNo

Common gotchas

  • chainId mismatch. The unsigned tx specifies a chain. Sign with a wallet whose nonce / chain matches. Otherwise the broadcast reverts.
  • Gas limit too tight. The MCP returns an estimated gasLimit; bump 20–30 % if you've seen recent reverts on full estimates.
  • Don't reuse nonces. If two MCP commitToOffer calls happen in parallel without nonce coordination, one fails. Serialize or assign nonces yourself.

Next