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.

Computes deterministic wallet addresses, calculates deployment and funding fees, and validates the payment payload. Call this before /deploy/settle to confirm addresses and costs. Two flows are available depending on how the payer signs the transaction.

EOA Deploy Verify

POST /deploy/verify
The payer signs EIP-712 TransferWithAuthorization payloads covering the deployment fee and optional funding amounts.

Request Body

FieldTypeRequiredDescription
paymentPayloadPaymentPayload[]YesArray of signed payments: 1 fee payload + up to 10 funding payloads
paymentRequirementsobjectYesNetwork and deployment configuration
paymentRequirements.networkstringYesTarget network ("bsc" or "base")
paymentRequirements.relayerContractstringYesb402 Relayer contract address
paymentRequirements.deploymentobjectYesDeployment parameters
paymentRequirements.deployment.ownerAddressstringYesOwner of the wallets to deploy
paymentRequirements.deployment.saltsstring[]Yes1-10 salts for deterministic address computation
paymentRequirements.deployment.fundingRequestedbooleanYesWhether to fund wallets after deployment
paymentRequirements.deployment.tokenstringYesERC-20 token contract address for fees and funding

Response (200)

FieldTypeDescription
isValidbooleanWhether the deployment can proceed
payerstringRecovered signer address
walletsobject[]Computed wallet details
wallets[].addressstringDeterministic wallet address
wallets[].saltstringSalt used for this wallet
wallets[].ownerstringOwner address
wallets[].fundingAmountstringAmount to fund this wallet (wei), "0" if funding not requested
deploymentFeestringFee for deploying all wallets (wei)
fundingFeesstringTotal funding amount across all wallets (wei)
totalFeesstringdeploymentFee + fundingFees (wei)
invalidReasonstring | nullReason for failure if isValid is false

cURL

curl -X POST https://facilitatorv3.b402.ai/deploy/verify \
  -H "Content-Type: application/json" \
  -d '{
    "paymentPayload": [
      {
        "token": "0x55d398326f99059fF775485246999027B3197955",
        "payload": {
          "authorization": {
            "from": "0xAbC1234567890aBcDeF1234567890AbCdEf123456",
            "to": "0xE91b564EB8DFF305Ff8efA332f84c487b9da5171",
            "value": "500000000000000000",
            "validAfter": 1709251200,
            "validBefore": 1709254800,
            "nonce": "0xaaa...fee_nonce"
          },
          "signature": "0x...fee_signature"
        }
      },
      {
        "token": "0x55d398326f99059fF775485246999027B3197955",
        "payload": {
          "authorization": {
            "from": "0xAbC1234567890aBcDeF1234567890AbCdEf123456",
            "to": "0xE91b564EB8DFF305Ff8efA332f84c487b9da5171",
            "value": "1000000000000000000",
            "validAfter": 1709251200,
            "validBefore": 1709254800,
            "nonce": "0xbbb...funding_nonce"
          },
          "signature": "0x...funding_signature"
        }
      }
    ],
    "paymentRequirements": {
      "network": "bsc",
      "relayerContract": "0xE91b564EB8DFF305Ff8efA332f84c487b9da5171",
      "deployment": {
        "ownerAddress": "0xAbC1234567890aBcDeF1234567890AbCdEf123456",
        "salts": ["0x1234...master_salt"],
        "fundingRequested": true,
        "token": "0x55d398326f99059fF775485246999027B3197955"
      }
    }
  }'

TypeScript

const response = await fetch("https://facilitatorv3.b402.ai/deploy/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    paymentPayload: [feePayload, ...fundingPayloads],
    paymentRequirements: {
      network: "bsc", // or "base"
      relayerContract: "0xE91b564EB8DFF305Ff8efA332f84c487b9da5171",
      deployment: {
        ownerAddress: wallet.address,
        salts: [masterSalt],
        fundingRequested: true,
        token: "0x55d398326f99059fF775485246999027B3197955",
      },
    },
  }),
});

const result = await response.json();

if (result.isValid) {
  console.log("Wallets to deploy:", result.wallets);
  console.log("Total fees:", result.totalFees);
  // Proceed to /deploy/settle
} else {
  console.error("Verification failed:", result.invalidReason);
}

Smart Wallet Deploy Verify

POST /deploy/wallet/verify
For smart wallet payers, the facilitator builds an unsigned UserOp instead of requiring pre-signed EIP-712 payloads. No paymentPayload is needed in the request.

Request Body

FieldTypeRequiredDescription
paymentRequirementsobjectYesNetwork and deployment configuration
paymentRequirements.networkstringYesTarget network ("bsc" or "base")
paymentRequirements.deploymentobjectYesDeployment parameters
paymentRequirements.deployment.ownerAddressstringYesOwner of the wallets to deploy
paymentRequirements.deployment.saltsstring[]Yes1-10 salts for deterministic address computation
paymentRequirements.deployment.tokenstringYesERC-20 token contract address for fees and funding
paymentRequirements.deployment.payerAddressstringYesSmart wallet address paying for deployment

Response (200)

Returns the same fields as the EOA response, plus:
FieldTypeDescription
userOpobjectUnsigned ERC-4337 UserOperation for the client to sign
userOpHashstringHash of the UserOp that the client must sign
All other fields (isValid, payer, wallets, deploymentFee, fundingFees, totalFees, invalidReason) are identical to the EOA response.

cURL

curl -X POST https://facilitatorv3.b402.ai/deploy/wallet/verify \
  -H "Content-Type: application/json" \
  -d '{
    "paymentRequirements": {
      "network": "bsc",
      "deployment": {
        "ownerAddress": "0xAbC1234567890aBcDeF1234567890AbCdEf123456",
        "salts": ["0x1234...master_salt"],
        "token": "0x55d398326f99059fF775485246999027B3197955",
        "payerAddress": "0x...nexus_smart_wallet"
      }
    }
  }'

TypeScript

const response = await fetch("https://facilitatorv3.b402.ai/deploy/wallet/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    paymentRequirements: {
      network: "bsc", // or "base"
      deployment: {
        ownerAddress: ownerAddress,
        salts: [masterSalt],
        token: "0x55d398326f99059fF775485246999027B3197955",
        payerAddress: smartWalletAddress,
      },
    },
  }),
});

const result = await response.json();

if (result.isValid) {
  console.log("UserOp hash to sign:", result.userOpHash);
  console.log("Wallets to deploy:", result.wallets);
  // Sign userOpHash, then call /deploy/wallet/settle
} else {
  console.error("Verification failed:", result.invalidReason);
}

Deterministic Address Computation

Wallet addresses are computed deterministically using CREATE2. Given the same owner, salt, and factory contract, the address is always the same, even before deployment.

Master Wallet Salt

The master wallet salt is derived from the owner address:
masterSalt = keccak256("b402-" + reversed(normalizedOwnerAddress))
Where normalizedOwnerAddress is the checksummed owner address with the 0x prefix removed, reversed as a string.
The master wallet is a special wallet that serves as the primary wallet for an owner. Each owner has exactly one deterministic master wallet. Sub-wallets use arbitrary salts.

Deployment Fee

A flat deployment fee is charged per wallet deployed. The fee is denominated in the token specified in paymentRequirements.deployment.token. The verify response includes the exact deploymentFee so you can confirm the cost before settling.

Optional Funding

When fundingRequested is true (EOA flow), the facilitator will fund each deployed wallet with the amounts specified in the funding payment payloads. Each funding payload corresponds to one wallet in the salts array, in order.

Error Codes

CodeHTTP StatusDescription
validation_error400Missing required fields, invalid salt format, or too many salts (max 10)
signature_error400EIP-712 signature is malformed or recovery failed
payment_verification_error400Insufficient balance, allowance too low, or token not whitelisted
blockchain_error500Failed to compute addresses or read on-chain state