Skip to main content
POST /wallet/verify builds an unsigned ERC-4337 UserOperation for a smart wallet payment. The facilitator validates the wallet, checks balances, injects the fee, estimates gas via the bundler, and returns a UserOp ready for the client to sign.

Base URL

https://facilitatorv3.b402.ai

Request

curl -X POST https://facilitatorv3.b402.ai/wallet/verify \
  -H "Content-Type: application/json" \
  -d '{
    "walletAddress": "0x...nexus_smart_wallet",
    "transactions": [
      {
        "to": "0x...recipient",
        "amount": "10000000000000000",
        "token": "0x55d398326f99059fF775485246999027B3197955"
      }
    ],
    "paymentRequirements": {
      "network": "bsc"
    }
  }'
const response = 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 data = await response.json();
// data.userOp      -> unsigned UserOp to sign
// data.userOpHash  -> hash the client must sign
// data.totalAmount -> original amount + facilitator fee

Request Body

FieldTypeRequiredDescription
walletAddressstringYesNexus smart wallet address (must already be deployed)
transactionsarrayYesArray of payment recipients (1-20 items)
transactions[].tostringYesRecipient address
transactions[].amountstringYesAmount in wei (token smallest unit)
transactions[].tokenstringYesERC-20 token contract address
paymentRequirementsobjectYesPayment configuration
paymentRequirements.networkstringYesTarget network ("bsc" or "base")
All transactions in a batch must use the same token address. Mixed-token batches are rejected.

Response

200 - Unsigned UserOp

{
  "isValid": true,
  "payer": "0x...wallet_owner",
  "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"
  },
  "userOpHash": "0x...hash_to_sign",
  "feeAmount": "50000000000000",
  "totalAmount": "10050000000000000"
}

Response Fields

FieldTypeDescription
isValidbooleanWhether the payment can proceed
payerstringAddress of the wallet owner (EOA that controls the smart wallet)
userOpobjectUnsigned ERC-4337 UserOperation
userOp.senderstringSmart wallet address executing the operation
userOp.noncestringWallet nonce (hex)
userOp.callDatastringEncoded batch call: approve(relayer, totalAmount) + transfers (hex)
userOp.callGasLimitstringGas limit for the main execution (hex)
userOp.verificationGasLimitstringGas limit for signature verification (hex)
userOp.preVerificationGasstringGas overhead for bundler processing (hex)
userOp.maxFeePerGasstringMaximum fee per gas unit (hex)
userOp.maxPriorityFeePerGasstringMaximum priority fee per gas unit (hex)
userOp.paymasterstringPaymaster contract address (covers gas for the user)
userOp.paymasterVerificationGasLimitstringGas limit for paymaster verification (hex)
userOp.paymasterPostOpGasLimitstringGas limit for paymaster post-operation (hex)
userOp.paymasterDatastringSigned paymaster authorization data (hex)
userOp.signaturestringEmpty (0x) - client must sign and populate this
userOpHashstringHash of the UserOp that the client must sign
feeAmountstringFacilitator fee in token wei
totalAmountstringamount + feeAmount - total deducted from wallet

Error Responses

StatusCodeDescription
400validation_errorInvalid request body, missing fields, or mixed tokens in batch
400validation_errorWallet not deployed at the given address
400validation_errorInsufficient token balance in wallet
400validation_errorBatch exceeds 20 transactions
500blockchain_errorFailed to read on-chain state or estimate gas

What Happens Server-Side

  1. Validates wallet - Confirms a deployed contract exists at walletAddress
  2. Checks balance - Reads the token balance in the smart wallet
  3. Builds batch call - Encodes approve(relayer, totalAmount) followed by the transfer calls into a single callData
  4. Injects fee - Adds the facilitator fee to the total
  5. Estimates gas - Calls the ERC-4337 bundler to estimate callGasLimit, verificationGasLimit, and preVerificationGas
  6. Signs paymaster data - The paymaster signs off on sponsoring the gas for this UserOp
  7. Returns unsigned UserOp - The client signs userOpHash and submits via /wallet/settle

Batch Payments

The transactions array supports 1 to 20 recipients in a single UserOp. All recipients must use the same token.
curl -X POST https://facilitatorv3.b402.ai/wallet/verify \
  -H "Content-Type: application/json" \
  -d '{
    "walletAddress": "0x...nexus_smart_wallet",
    "transactions": [
      {
        "to": "0x...recipient_1",
        "amount": "5000000000000000",
        "token": "0x55d398326f99059fF775485246999027B3197955"
      },
      {
        "to": "0x...recipient_2",
        "amount": "3000000000000000",
        "token": "0x55d398326f99059fF775485246999027B3197955"
      }
    ],
    "paymentRequirements": {
      "network": "bsc"
    }
  }'
The facilitator sums all amounts, adds a single fee, and encodes the full batch into one UserOp.

Next Step

After receiving the response, sign the userOpHash with the wallet owner’s private key and submit the signed UserOp to POST /wallet/settle.