Docs/WDK/Quickstart

>_ WDK / QUICKSTART

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.

⌘KCommand-palette first navJump:QuickstartAPIErrorsMigrationSecurity

Prerequisites

  • 1.A P402 API key — create one at p402.io/dashboard
  • 2.A WDK-compatible wallet (Tether WDK v1.0.0+)
  • 3.USDT0 balance on Arbitrum One (eip155:42161) or USDC on Base (eip155:8453)
  • 4.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

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

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

2

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.

typescript — sign with WDK adapter
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,
});
3

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

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).

json — 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