Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Troubleshooting — Signature mismatches · Boson Protocol
Skip to content

Signature mismatches

Symptom

A meta-tx or mutual-resolve call reverts with SignatureValidationFailed (or "recovered address doesn't match expected").

Causes (in rough order of likelihood)

  1. Wrong typed-data structure. Hand-built typed-data drifts from the on-chain verifier.
  2. Wrong domain separator. Chain ID or verifying-contract mismatch.
  3. Hardware wallet quirk. Some HW wallets corrupt long typed-data; check firmware.
  4. EIP-1271 smart-account signature when the verifier expects EOA, or vice versa.
  5. Stale nonce. Signature for nonce N submitted at nonce N+1.
  6. Wrong signer. Someone other than the expected user signed.

Fix

Always use the SDK / MCP signing helpers

// CORRECT
const signed = await sdk.metaTx.signMetaTxCommitToOffer({ buyer, offerId })
 
// WRONG: do not hand-build
const signed = await wallet._signTypedData(domain, types, message) // domain drifts!

The SDK builds the typed-data identically to the on-chain verifier. Hand-built typed-data is the #1 cause of mismatches.

Check the domain

The EIP-712 domain must match the on-chain verifier exactly:

{
  name: "BosonProtocolDiamond",
  version: "V2",
  chainId: <actual chain id>,
  verifyingContract: <Diamond address for this configId>,
}

A chainId mismatch causes recovered addresses to be junk. If you're on Polygon production, the chainId must be 137 — not 1, not 80002.

For smart accounts

The Diamond accepts EIP-1271 signatures. If your buyer is a Safe, the signing flow is:

  1. Safe owners sign the inner data offline.
  2. Combine into a Safe signature blob.
  3. The blob is what gets passed as the meta-tx signature.

The Diamond calls IERC1271.isValidSignature(hash, sig) on the buyer address. Make sure your Safe is deployed at the address you're using.

Nonce check

const nonce = await diamond.getNonce(userAddress)
// ensure the signature you produce uses exactly this nonce

Debugging

If SignatureValidationFailed is intermittent under concurrency, you have a nonce race. Serialize signing or generate fresh nonces.

Related