Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.b402.ai/llms.txt

Use this file to discover all available pages before exploring further.

POST /wallet/settle takes the signed UserOperation from /wallet/verify and submits it to the ERC-4337 bundler for on-chain execution. The facilitator polls for the receipt and returns the transaction hash with payment details.

Base URL

https://facilitatorv3.b402.ai

Request

curl -X POST https://facilitatorv3.b402.ai/wallet/settle \
  -H "Content-Type: application/json" \
  -d '{
    "userOp": {
      "sender": "0x...wallet_address",
      "nonce": "0x...",
      "callData": "0x...encoded_batch_call",
      "callGasLimit": "0x...",
      "verificationGasLimit": "0x...",
      "preVerificationGas": "0x...",
      "maxFeePerGas": "0x...",
      "maxPriorityFeePerGas": "0x...",
      "paymaster": "0x...",
      "paymasterVerificationGasLimit": "0x...",
      "paymasterPostOpGasLimit": "0x...",
      "paymasterData": "0x...",
      "signature": "0x...user_signature_of_userOpHash"
    },
    "signature": "0x...user_signature_of_userOpHash"
  }'
import { Wallet } from 'ethers';

// 1. Get unsigned UserOp from /wallet/verify
const verifyRes = await fetch('https://facilitatorv3.b402.ai/wallet/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    walletAddress: '0x...nexus_smart_wallet',
    transactions: [
      {
        to: '0x...recipient',
        amount: '10000000000000000',
        token: '0x55d398326f99059fF775485246999027B3197955',
      },
    ],
    paymentRequirements: { network: 'bsc' }, // or 'base'
  }),
});
const { userOp, userOpHash } = await verifyRes.json();

// 2. Sign the userOpHash with the wallet owner's key
const ownerWallet = new Wallet(process.env.PRIVATE_KEY);
const signature = await ownerWallet.signMessage(
  Buffer.from(userOpHash.slice(2), 'hex')
);

// 3. Submit signed UserOp to /wallet/settle
const settleRes = await fetch('https://facilitatorv3.b402.ai/wallet/settle', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    userOp: { ...userOp, signature },
    signature,
  }),
});

const result = await settleRes.json();
console.log('TX:', result.txHash);

Request Body

FieldTypeRequiredDescription
userOpobjectYesThe full UserOperation object returned by /wallet/verify, with the signature field populated
userOp.signaturestringYesUser’s signature of the userOpHash (hex)
signaturestringYesSame user signature, provided at the top level for validation
The userOp object must contain all fields exactly as returned by /wallet/verify. Do not modify any field other than signature.

Response

200 - Settlement Successful

{
  "success": true,
  "txHash": "0x...",
  "userOpHash": "0x...",
  "payments": [
    {
      "to": "0x...recipient",
      "amount": "10000000000000000",
      "token": "0x...token"
    }
  ]
}

Response Fields

FieldTypeDescription
successbooleanWhether the transaction was mined successfully
txHashstringOn-chain transaction hash (use on BscScan or b402scan to inspect)
userOpHashstringUserOperation hash matching the one from /wallet/verify
paymentsarrayParsed payment events extracted from transaction logs
payments[].tostringRecipient address
payments[].amountstringAmount transferred in token wei
payments[].tokenstringERC-20 token contract address

Error Responses

StatusCodeDescription
400validation_errorMissing or malformed userOp or signature
400validation_errorSignature does not match the userOpHash
400userop_errorBundler rejected the UserOp (insufficient gas, nonce conflict, paymaster denial)
500blockchain_errorTransaction reverted or receipt polling timed out

What Happens Server-Side

  1. Injects signature - Places the user’s signature into the UserOp
  2. Submits to bundler - Sends the signed UserOp to the ERC-4337 bundler via eth_sendUserOperation
  3. Polls for receipt - Waits for the bundler to mine the transaction and return a receipt
  4. Extracts payment events - Parses Transfer events from the transaction logs to build the payments array
  5. Returns result - Responds with the transaction hash and payment breakdown

Error Handling

Bundler-level failures return userop_error. Common causes:
CauseWhat To Do
Nonce already usedRe-call /wallet/verify to get a fresh UserOp
Paymaster expiredRe-call /wallet/verify for new paymaster data
Insufficient balanceToken balance changed between verify and settle
Gas estimation mismatchNetwork conditions changed; retry from verify
For all userop_error and blockchain_error responses, the safe recovery path is to re-call /wallet/verify and restart the flow.

Full Flow

Client                          Facilitator                    Bundler / Chain
  |                                  |                                |
  |  POST /wallet/verify             |                                |
  |  { walletAddress, transactions } |                                |
  |--------------------------------->|                                |
  |                                  |-- validate wallet, balance     |
  |                                  |-- build callData + fee         |
  |                                  |-- estimate gas via bundler --->|
  |                                  |<--- gas estimates -------------|
  |                                  |-- sign paymaster data          |
  |  { userOp, userOpHash }         |                                |
  |<---------------------------------|                                |
  |                                  |                                |
  |  sign(userOpHash)                |                                |
  |                                  |                                |
  |  POST /wallet/settle             |                                |
  |  { userOp + signature }          |                                |
  |--------------------------------->|                                |
  |                                  |-- eth_sendUserOperation ------>|
  |                                  |-- poll for receipt ----------->|
  |                                  |<--- receipt + logs ------------|
  |  { txHash, payments }            |                                |
  |<---------------------------------|                                |