WDK QUICKSTART

Integrate WDK + USDT0 settlement with P402 in ~15 minutes. You'll quote a route, sign an authorization with your WDK wallet, settle on-chain, and read the receipt.

Prerequisites

    1. A P402 API key — create one at p402.io/dashboard
    1. A WDK-compatible wallet (Tether WDK v1.0.0+)
    1. USDT0 balance on Arbitrum One (eip155:42161) or USDC on Base (eip155:8453)
    1. Node.js ≥ 18 or curl for the code examples

What is WDK?

WDK (Wallet Development Kit) is Tether's signer abstraction for USDT0, the bridged USDT token on EVM chains. Where USDC uses EIP-3009 (TransferWithAuthorization), USDT0 on supported chains uses the same EIP-3009 path — but USDT0's contract surface varies by chain and deployment version. WDK normalizes this.

P402 treats WDK as an authType in the settlement request. When you set authType: "eip3009" with asset: "USDT0", P402 routes the settlement through the appropriate facilitator for your source chain.

Token rail decision

  • USDT0: Use authType: "eip3009". Supported on Arbitrum One, Base, and Ethereum (verify contract version per chain before integration).
  • Legacy USDT: Do not use EIP-3009. Legacy USDT does not implement transferWithAuthorization. Use the permit/transfer fallback or bridge to USDT0 first.
  • USDC: Use authType: "eip3009" with asset: "USDC". This is the standard baseline — no WDK adapter needed.

Request a Quote

Before settling, get a quote. The quote selects the best route for your token, chain, and constraints, and returns a quoteId and a list of available routes. Quotes expire after 60 seconds.

curl -X POST https://p402.io/api/v1/liquidity/quote \
  -H "Authorization: Bearer $P402_API_KEY" \
  -H "Content-Type: application/json" \
  -d ' {\n    "invoiceId": "inv_123",\n    "walletAddress": "0xYourWalletAddress",\n    "sourceAssets": ["USDT0", "USDT", "USDC"],\n    "constraints": {\n      "maxFeeBps": 75,\n      "maxLatencyMs": 12000\n    }\n  }' 

quote response

{  
  "quoteId": "q_123",  
  "expiresAt": "2026-04-16T12:01:00.000Z",  
  "routes": [\ 
    {\ 
      "routeId": "r_fast",\ 
      "sourceAsset": "USDT0",\ 
      "sourceChain": "eip155:42161",      // Arbitrum One\ 
      "destinationChain": "eip155:8453",  // Base\ 
      "authType": "eip3009",\ 
      "estimatedFeeBps": 42,              // 0.42% total fee\ 
      "estimatedLatencyMs": 3200\ 
    }\ 
  ]\ 
}

Select the route you want to use and save both quoteId and routeId for the next step.

Sign with WDK

Use your WDK signer to create an EIP-712 TransferWithAuthorization. The nonce must be a 32-byte hex string that has never been used before for this wallet.

import { WdkSigner } from '@tether/wdk';  // Your WDK signer instance

const USDT0_ADDRESS = '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9'; // Arbitrum
const P402_TREASURY = '0xFa772434DCe6ED78831EbC9eeAcbDF42E2A031a6';

// Amount in atomic units (USDT0 has 6 decimals: 1.00 USDT0 = 1_000_000)
const amount = '1000000';

// Nonce: 32-byte random hex, never reused for this wallet
const nonce = '0x' + crypto.getRandomValues(new Uint8Array(32))
  .reduce((hex, b) => hex + b.toString(16).padStart(2, '0'), '');

const now = Math.floor(Date.now() / 1000);

const authorization = {
  from: walletAddress,
  to: P402_TREASURY,
  value: amount,
  validAfter: String(now - 60),    // Allow 1 minute of clock skew
  validBefore: String(now + 3600), // Expires in 1 hour
  nonce,
};

// WDK signs the EIP-712 typed data for TransferWithAuthorization
const signature = await wdkSigner.signTransferAuthorization({
  token: USDT0_ADDRESS,
  chainId: 42161,  // Arbitrum One
  authorization,
});

Submit Settlement

Submit the signed authorization to P402. The facilitator verifies the signature, executes the on-chain transfer (paying gas), and returns a receipt.

curl -X POST https://p402.io/api/v1/router/settle \
  -H "Authorization: Bearer $P402_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{\n    "quoteId": "q_123",\n    "routeId": "r_fast",\n    "client": { "type": "wdk", "version": "1.0.0" },\n    "authType": "eip3009",\n    "amount": "1.00",\n    "asset": "USDT0",\n    "payment": {\n      "scheme": "exact",\n      "authorization": {\n        "from": "0xYourWalletAddress",\n        "to": "0xFa772434DCe6ED78831EbC9eeAcbDF42E2A031a6",\n        "value": "1000000",\n        "validAfter": "1713261600",\n        "validBefore": "1713265200",\n        "nonce": "0xabc123..."\n      },\n      "signature": "0x..."\n    }\n  }'

Read the Receipt

A successful settlement returns a receipt. Save the txHash for audit purposes and the receipt.receipt_id for the receipt scheme (reuse a prior payment without re-signing).

settlement response

{  
  "settled": true,  
  "facilitatorId": "p402-eip3009",  
  "receipt": {  
    "receipt_id": "rec_abc789",  
    "txHash": "0x...",  
    "sourceAsset": "USDT0",  
    "sourceChain": "eip155:42161",  
    "destinationChain": "eip155:8453",  
    "amount": "1.00",  
    "routeId": "r_fast",  
    "settled_at": "2026-04-16T12:00:05.000Z"  
  }  
}

Receipt scheme (idempotency)

To reuse a prior payment (e.g. retry on network failure without double-spending), pass authType: "receipt" and receipt_id: "rec_abc789" instead of a new signature. P402 verifies the receipt is unused and settles once.

Keyboard shortcuts

  • ⌘K — Open docs command palette
  • g a — Jump to API reference
  • g e — Jump to error codes

Next Steps