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
- A P402 API key — create one at p402.io/dashboard
- A WDK-compatible wallet (Tether WDK v1.0.0+)
- USDT0 balance on Arbitrum One (eip155:42161) or USDC on Base (eip155:8453)
- 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
- Visit the API Reference for full endpoint contracts for quote, settle, and receipt.
- Refer to the Error Codes for handling failures and retries.
- Check the Migration Guide for moving from USDC-only to WDK + USDT0.
- Understand Security & Privacy for operational security.