ResourcesChains & Networks

Chains & Networks

49 Networks
11 Chain Families
77 Payment Kinds

EVM Chains (Mainnet)

ChainNetwork IDUSDT0USDCGasless
Ethereumeip155:1
Arbitrumeip155:42161
Baseeip155:8453
Optimismeip155:10
Polygoneip155:137
Inkeip155:57073-
Berachaineip155:80094-
Unichaineip155:130-
Mantleeip155:5000-
Seieip155:1329-
BNB Chaineip155:56--
Avalancheeip155:43114--
Fantomeip155:250--
Celoeip155:42220--
Kaiaeip155:8217--
Confluxeip155:1030-
Monadeip155:143-
Rootstockeip155:30-
XLayereip155:196-
MegaETHeip155:4326-
Flareeip155:14-
HyperEVMeip155:999-
Plasmaeip155:9745-
Stableeip155:988-
Corneip155:21000000-

EVM Chains (Testnet)

ChainNetwork IDUSDT0USDCGasless
Sepoliaeip155:11155111
Base Sepoliaeip155:84532
Arbitrum Sepoliaeip155:421614
Ink Sepoliaeip155:763373-
Berachain bArtioeip155:80084-
Unichain Sepoliaeip155:1301-

Non-EVM Chains

ChainMainnet IDTestnet IDTokenStatus
TONton:mainnetton:testnetUSDT JettonProduction
TRONtron:mainnettron:nile, tron:shastaUSDT TRC-20Production
Solanasolana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpsolana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1USDC SPLProduction
NEARnear:mainnetnear:testnetUSDT NEP-141Production
Aptosaptos:1aptos:2USDT FAProduction
Tezostezos:NetXdQprcVkpaWUtezos:NetXnHfVqm9iespUSDt FA2Production
Polkadot Asset Hubpolkadot:68d56f15f85d3136970ec16946040bc1polkadot:e143f23803ac50e8f6f8e62695d1ce9eUSDT (Asset 1984)Production
Stacksstacks:1stacks:2147483648sUSDC SIP-010Production
Cosmos (Noble)cosmos:noble-1cosmos:grand-1USDC nativeProduction

Network identifiers follow CAIP-2 format. Some chains use genesis block hashes (Solana, Tezos, Polkadot) while others use chain IDs (EVM, Aptos, Stacks).

USDT0 Addresses

USDT0 is the new Omnichain Fungible Token (OFT) version of USDT with EIP-3009 support.

ChainAddress
Ethereum0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee
Arbitrum0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
Ink0x0200C29006150606B650577BBE7B6248F58470c1
Berachain0x779Ded0c9e1022225f8E0630b35a9b54bE713736
Unichain0x9151434b16b9763660705744891fA906F660EcC5

NEAR Token Addresses

TokenNetworkContract IDDecimals
USDTMainnetusdt.tether-token.near6
USDCMainnet17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a16
USDCTestnetusdc.fakes.testnet6

Aptos Token Addresses (Fungible Asset)

TokenNetworkMetadata AddressDecimals
USDTMainnet0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb6
USDCMainnet0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b6

Tezos Token Addresses (FA2)

TokenNetworkContractToken IDDecimals
USDtMainnetKT1XnTn74bUtxHfDtBmm2bGZAQfhPbvKWR8o06

Polkadot Asset Hub

TokenNetworkAsset IDDecimals
USDTPolkadot Asset Hub19846
USDTKusama Asset Hub19846
USDTWestend Asset Hub (testnet)19846

Stacks Token Addresses (SIP-010)

TokenNetworkContractDecimals
sUSDCMainnetSP3Y2ZSH8P7D50B0VBTSX11S7XSG24M1VB9YFQA4K.token-susdc6
sUSDCTestnetST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.token-susdc6

Cross-Chain Bridging

USDT0 supports cross-chain transfers via LayerZero OFT:

RouteEstimated Time
Ethereum ↔ Arbitrum~3-15 minutes
L2 ↔ L2~5 minutes
Any ↔ Ethereum~15 minutes

See @t402/wdk-bridge for bridging integration.

Network Selection

When configuring T402, use the CAIP-2 network ID format:

// EVM chains
'eip155:1'      // Ethereum
'eip155:8453'   // Base
'eip155:42161'  // Arbitrum
 
// Non-EVM chains
'ton:mainnet'                                    // TON
'tron:mainnet'                                   // TRON
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'       // Solana Mainnet
'near:mainnet'                                   // NEAR
'aptos:1'                                        // Aptos Mainnet
'tezos:NetXdQprcVkpaWU'                         // Tezos Mainnet
'polkadot:68d56f15f85d3136970ec16946040bc1'    // Polkadot Asset Hub
'stacks:1'                                       // Stacks Mainnet
'cosmos:noble-1'                                 // Noble (Cosmos)

Adding New Chains

T402 is extensible. To add support for a new chain:

  1. Implement the scheme interface for your chain
  2. Register the scheme with the client/server
  3. Submit a PR to the T402 repository

See the Contributing Guide for details.


EVM Chains

Detailed guide for EVM (Ethereum Virtual Machine) compatible chains. T402 supports all major EVM chains through the @t402/evm package.

Layer 2 Benefits
BenefitDescription
Lower gas~100x cheaper than Ethereum mainnet
Faster finalitySeconds vs minutes
Same securitySecured by Ethereum
Same addressesUse same wallet across L2s
Server Setup
import { t402ResourceServer, createFacilitatorClient } from '@t402/core/server';
import { registerExactEvmScheme } from '@t402/evm/exact/server';
 
const facilitator = createFacilitatorClient({
  url: 'https://facilitator.t402.io',
});
 
const server = new t402ResourceServer(facilitator);
registerExactEvmScheme(server, {});
 
// Configure routes
const routes = {
  '/api/premium/*': {
    accepts: [
      { scheme: 'exact', network: 'eip155:8453', payTo: '0x...', price: '$0.01' },
      { scheme: 'exact', network: 'eip155:42161', payTo: '0x...', price: '$0.01' },
    ],
  },
};
Client Setup
import { t402Client } from '@t402/core/client';
import { ExactEvmScheme } from '@t402/evm/exact/client';
import { createWalletClient, custom } from 'viem';
import { base } from 'viem/chains';
 
// Create viem wallet client
const walletClient = createWalletClient({
  chain: base,
  transport: custom(window.ethereum),
});
 
// Create T402 client
const client = new t402Client();
client.register('eip155:*', new ExactEvmScheme(walletClient));
EIP-3009 (TransferWithAuthorization)

T402 uses EIP-3009 for gasless token transfers.

How It Works
  1. User signs an off-chain authorization message
  2. Facilitator executes the transferWithAuthorization on-chain
  3. User pays no gas - facilitator covers gas costs
Authorization Structure
interface TransferWithAuthorization {
  from: string;        // Payer address
  to: string;          // Recipient address
  value: bigint;       // Amount in smallest unit
  validAfter: bigint;  // Unix timestamp (usually 0)
  validBefore: bigint; // Deadline timestamp
  nonce: bytes32;      // Random nonce
}
Signature Verification

The EIP-712 typed data structure:

const domain = {
  name: 'USD0',
  version: '1',
  chainId: 8453,
  verifyingContract: '0x...',
};
 
const types = {
  TransferWithAuthorization: [
    { name: 'from', type: 'address' },
    { name: 'to', type: 'address' },
    { name: 'value', type: 'uint256' },
    { name: 'validAfter', type: 'uint256' },
    { name: 'validBefore', type: 'uint256' },
    { name: 'nonce', type: 'bytes32' },
  ],
};
Gas Estimation
Average Costs by Chain
ChainTransfer CostSettlement Cost
Ethereum~$5-50~$10-100
Arbitrum~$0.01-0.10~$0.02-0.20
Base~$0.001-0.01~$0.002-0.02
Optimism~$0.01-0.10~$0.02-0.20

Gas costs vary with network congestion. L2s are generally 100x cheaper than Ethereum mainnet.

Programmatic Estimation
import { estimateGas } from '@t402/evm';
 
const estimate = await estimateGas({
  network: 'eip155:8453',
  operation: 'transferWithAuthorization',
  rpcUrl: 'https://mainnet.base.org',
});
 
console.log(`Estimated gas: ${estimate.gasLimit}`);
console.log(`Estimated cost: $${estimate.costUsd}`);
Multi-Chain Support
Same Address Across Chains

EVM addresses work across all EVM chains:

const payToAddress = '0x742d35Cc6634C0532925a3b844Bc9e7595f5b1A1';
 
const routes = {
  '/api/premium/*': {
    accepts: [
      { scheme: 'exact', network: 'eip155:1', payTo: payToAddress, price: '$0.01' },
      { scheme: 'exact', network: 'eip155:8453', payTo: payToAddress, price: '$0.01' },
      { scheme: 'exact', network: 'eip155:42161', payTo: payToAddress, price: '$0.01' },
    ],
  },
};
User Network Selection

Let users choose their preferred chain:

import { getNetworkDisplayName, getChainConfig } from '@t402/evm';
 
const supportedNetworks = [
  'eip155:8453',   // Base
  'eip155:42161',  // Arbitrum
  'eip155:10',     // Optimism
];
 
// Display network options to user
supportedNetworks.forEach(network => {
  const config = getChainConfig(network);
  console.log(`${getNetworkDisplayName(network)}: ~$${config.avgGasCost}`);
});
Wallet Integration
MetaMask
// Request account access
await window.ethereum.request({ method: 'eth_requestAccounts' });
 
// Get current chain
const chainId = await window.ethereum.request({ method: 'eth_chainId' });
 
// Switch to Base
await window.ethereum.request({
  method: 'wallet_switchEthereumChain',
  params: [{ chainId: '0x2105' }], // Base = 8453 = 0x2105
});
WalletConnect
import { createWalletClient } from 'viem';
import { WalletConnectConnector } from '@wagmi/connectors/walletConnect';
 
const connector = new WalletConnectConnector({
  options: {
    projectId: 'your-project-id',
    chains: [base, arbitrum, optimism],
  },
});
 
await connector.connect();
const walletClient = await connector.getWalletClient();
Safe Multi-Sig
import { createMultisigClient } from '@t402/wdk-multisig';
 
const multisigClient = await createMultisigClient({
  safeAddress: '0xYourSafeAddress',
  chainId: 8453,
  owners: ['0xOwner1', '0xOwner2', '0xOwner3'],
  threshold: 2,
});
RPC Endpoints
ChainPublic RPCPaid Options
Ethereumhttps://eth.llamarpc.comAlchemy, Infura
Arbitrumhttps://arb1.arbitrum.io/rpcAlchemy, QuickNode
Basehttps://mainnet.base.orgAlchemy, QuickNode
Optimismhttps://mainnet.optimism.ioAlchemy, QuickNode
Configuration
const rpcConfig = {
  'eip155:1': process.env.ETH_RPC_URL || 'https://eth.llamarpc.com',
  'eip155:8453': process.env.BASE_RPC_URL || 'https://mainnet.base.org',
  'eip155:42161': process.env.ARB_RPC_URL || 'https://arb1.arbitrum.io/rpc',
};
Troubleshooting
Common Issues
IssueCauseSolution
”Invalid signature”Wrong chain IDVerify network matches
”Insufficient funds”No USDT balanceFund wallet with USDT
”Nonce already used”Replay attemptGenerate new nonce
”Deadline passed”Authorization expiredSign new authorization
Debugging
import { verifySignature, decodePayment } from '@t402/evm';
 
// Decode payment header
const payment = decodePayment(xPaymentHeader);
console.log('Payment details:', payment);
 
// Verify signature locally
const isValid = await verifySignature({
  message: payment.message,
  signature: payment.signature,
  expectedSigner: payment.from,
});
console.log('Signature valid:', isValid);

Non-EVM Chains

Guide for integrating T402 with non-EVM blockchain networks. T402 supports 9 non-EVM blockchain networks:

ChainPackageToken StandardStatus
TON@t402/tonJettonProduction
TRON@t402/tronTRC-20Production
Solana@t402/svmSPL TokenProduction
NEAR@t402/nearNEP-141Production
Aptos@t402/aptosFungible AssetProduction
Tezos@t402/tezosFA2Production
Polkadot@t402/polkadotAsset HubProduction
Stacks@t402/stacksSIP-010Production
Cosmos (Noble)@t402/cosmosBank MsgSendProduction

TON (The Open Network)

PropertyValue
Network IDton:mainnet, ton:testnet
TokenUSDT Jetton
SignatureEd25519
Finality~5 seconds

Token Addresses:

NetworkJetton Master
MainnetEQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs
TestnetkQD0GKBM8ZbryVk2aESmzfU6b9b_8era_IkvBSELujFZPsyy
import { registerExactTonScheme } from '@t402/ton/exact/server';
import { ExactTonScheme } from '@t402/ton/exact/client';
 
// Server
registerExactTonScheme(server, {});
 
// Client
const tonClient = new ExactTonScheme(tonConnectUI);
client.register('ton:mainnet', tonClient);
TON Connect
import { TonConnectUI } from '@tonconnect/ui';
 
const tonConnectUI = new TonConnectUI({
  manifestUrl: 'https://yourapp.com/tonconnect-manifest.json',
});
 
await tonConnectUI.connectWallet();

TRON

PropertyValue
Network IDtron:mainnet, tron:nile, tron:shasta
TokenUSDT TRC-20
SignatureECDSA secp256k1
Finality~3 seconds

Token Addresses:

NetworkContract
MainnetTR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
NileTXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf
import { registerExactTronScheme } from '@t402/tron/exact/server';
import { ExactTronScheme } from '@t402/tron/exact/client';
 
// Server
registerExactTronScheme(server, {});
 
// Client (with TronLink)
const tronWeb = window.tronWeb;
const tronClient = new ExactTronScheme(tronWeb);
client.register('tron:mainnet', tronClient);
⚠️

TRON uses Energy for smart contract execution. Ensure accounts have sufficient Energy or TRX for gas.

Solana

PropertyValue
Network IDsolana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp (mainnet)
TokenUSDC SPL Token
SignatureEd25519
Finality~400ms

Token Addresses:

NetworkMint Address
MainnetEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
Devnet4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU
import { registerExactSvmScheme } from '@t402/svm/exact/server';
import { ExactSvmScheme } from '@t402/svm/exact/client';
import { useWallet } from '@solana/wallet-adapter-react';
 
// Server
registerExactSvmScheme(server, {});
 
// Client (with Phantom)
const { signMessage, publicKey } = useWallet();
const svmClient = new ExactSvmScheme({ signMessage, publicKey });
client.register('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', svmClient);

NEAR

PropertyValue
Network IDnear:mainnet, near:testnet
TokenUSDT NEP-141
SignatureEd25519
Finality~2 seconds

Token Addresses:

NetworkContract ID
Mainnetusdt.tether-token.near
Testnetusdt.fakes.testnet
import { registerExactNearScheme } from '@t402/near/exact/server';
import { ExactNearScheme } from '@t402/near/exact/client';
 
// Server
registerExactNearScheme(server, {});
 
// Client
const nearClient = new ExactNearScheme(wallet);
client.register('near:mainnet', nearClient);

Aptos

PropertyValue
Network IDaptos:1 (mainnet), aptos:2 (testnet)
TokenUSDT Fungible Asset
SignatureEd25519
Finality~1 second
import { registerExactAptosScheme } from '@t402/aptos/exact/server';
import { ExactAptosScheme } from '@t402/aptos/exact/client';
 
// Server
registerExactAptosScheme(server, {});
 
// Client
const aptosClient = new ExactAptosScheme(wallet);
client.register('aptos:1', aptosClient);

Tezos

PropertyValue
Network IDtezos:NetXdQprcVkpaWU (mainnet)
TokenUSDt FA2 (TZIP-12)
SignatureEd25519/secp256k1/P256
Finality~30 seconds
import { registerExactTezosScheme } from '@t402/tezos/exact/server';
import { ExactTezosScheme } from '@t402/tezos/exact/client';
 
// Server
registerExactTezosScheme(server, {});
 
// Client
const tezosClient = new ExactTezosScheme(wallet);
client.register('tezos:NetXdQprcVkpaWU', tezosClient);

Polkadot Asset Hub

PropertyValue
Network IDpolkadot:68d56f15f85d3136970ec16946040bc1
TokenUSDT (Asset ID 1984)
SignatureSr25519/Ed25519
Finality~12 seconds
import { registerExactPolkadotScheme } from '@t402/polkadot/exact/server';
import { ExactPolkadotScheme } from '@t402/polkadot/exact/client';
 
// Server
registerExactPolkadotScheme(server, {});
 
// Client
const polkadotClient = new ExactPolkadotScheme(wallet);
client.register('polkadot:68d56f15f85d3136970ec16946040bc1', polkadotClient);

Stacks (Bitcoin L2)

PropertyValue
Network IDstacks:1 (mainnet), stacks:2147483648 (testnet)
TokensUSDC SIP-010
Signaturesecp256k1
FinalityBitcoin block (~10 min)
import { registerExactStacksScheme } from '@t402/stacks/exact/server';
import { ExactStacksScheme } from '@t402/stacks/exact/client';
 
// Server
registerExactStacksScheme(server, {});
 
// Client
const stacksClient = new ExactStacksScheme(wallet);
client.register('stacks:1', stacksClient);

Cosmos (Noble)

PropertyValue
Network IDcosmos:noble-1 (mainnet), cosmos:grand-1 (testnet)
TokenUSDC native
Signaturesecp256k1
Finality~6 seconds
import { registerExactCosmosScheme } from '@t402/cosmos/exact/server';
import { ExactCosmosScheme } from '@t402/cosmos/exact/client';
 
// Server
registerExactCosmosScheme(server, {});
 
// Client
const cosmosClient = new ExactCosmosScheme(wallet);
client.register('cosmos:noble-1', cosmosClient);
Multi-Chain Server

Support all non-EVM chains:

import { t402ResourceServer, createFacilitatorClient } from '@t402/core/server';
import { registerExactTonScheme } from '@t402/ton/exact/server';
import { registerExactTronScheme } from '@t402/tron/exact/server';
import { registerExactSvmScheme } from '@t402/svm/exact/server';
import { registerExactNearScheme } from '@t402/near/exact/server';
import { registerExactAptosScheme } from '@t402/aptos/exact/server';
import { registerExactTezosScheme } from '@t402/tezos/exact/server';
import { registerExactPolkadotScheme } from '@t402/polkadot/exact/server';
import { registerExactStacksScheme } from '@t402/stacks/exact/server';
import { registerExactCosmosScheme } from '@t402/cosmos/exact/server';
 
const server = new t402ResourceServer(facilitator);
 
// Register all mechanisms
registerExactTonScheme(server, {});
registerExactTronScheme(server, {});
registerExactSvmScheme(server, {});
registerExactNearScheme(server, {});
registerExactAptosScheme(server, {});
registerExactTezosScheme(server, {});
registerExactPolkadotScheme(server, {});
registerExactStacksScheme(server, {});
registerExactCosmosScheme(server, {});
 
// Configure routes
const routes = {
  '/api/premium/*': {
    accepts: [
      { scheme: 'exact', network: 'ton:mainnet', payTo: 'EQ...', price: '$0.01' },
      { scheme: 'exact', network: 'tron:mainnet', payTo: 'T...', price: '$0.01' },
      { scheme: 'exact', network: 'solana:5eykt...', payTo: '...', price: '$0.01' },
      { scheme: 'exact', network: 'near:mainnet', payTo: 'account.near', price: '$0.01' },
      { scheme: 'exact', network: 'aptos:1', payTo: '0x...', price: '$0.01' },
      { scheme: 'exact', network: 'tezos:NetXdQprcVkpaWU', payTo: 'tz1...', price: '$0.01' },
      { scheme: 'exact', network: 'polkadot:68d56f...', payTo: '15...', price: '$0.01' },
      { scheme: 'exact', network: 'stacks:1', payTo: 'SP...', price: '$0.01' },
      { scheme: 'exact', network: 'cosmos:noble-1', payTo: 'noble1...', price: '$0.01' },
    ],
  },
};
Non-EVM Chain Comparison
FeatureTONTRONSolanaNEARAptosTezosPolkadotStacksCosmos
Finality5s3s400ms2s1s30s12s10min6s
Avg Fee$0.01$0.10$0.0001$0.001$0.001$0.01$0.01$0.05$0.001
SignatureEd25519ECDSAEd25519Ed25519Ed25519MultiSr25519ECDSAsecp256k1

Bitcoin & Lightning

Guide for integrating T402 with Bitcoin on-chain (PSBT) and Lightning Network (BOLT11) payments.

T402 supports Bitcoin through two payment methods:

MethodNetwork IDPayloadSettlementBest For
On-chain (PSBT)bip122:000000000019d6689c085ae165831e93Signed PSBT~10 min (1 confirmation)Larger payments
Lightning (BOLT11)lightning:mainnetPreimageInstant (~seconds)Micropayments
Network Identifiers

Bitcoin uses BIP-122 chain genesis block hashes as CAIP-2 identifiers:

NetworkCAIP-2 ID
BTC Mainnetbip122:000000000019d6689c085ae165831e93
BTC Testnetbip122:000000000933ea01ad0ee984209779ba
Lightning Mainnetlightning:mainnet
Lightning Testnetlightning:testnet
On-Chain (PSBT)

Bitcoin on-chain payments use BIP-174 Partially Signed Bitcoin Transactions (PSBT). The client creates and signs a PSBT, the facilitator verifies the outputs and broadcasts it.

Payment Flow
  1. Server returns 402 with network: "bip122:000000000019d6689c085ae165831e93" and payTo (Bitcoin address)
  2. Client builds a PSBT with the required output (payTo address + amount in satoshis)
  3. Client signs the PSBT and submits it as the payment payload
  4. Facilitator verifies the PSBT outputs match requirements
  5. Facilitator finalizes and broadcasts the transaction
  6. Facilitator waits for confirmation and returns the txid
Supported Address Types
  • P2WPKH (bc1q…) — Native SegWit
  • P2TR (bc1p…) — Taproot
  • P2PKH (1…) — Legacy
  • P2SH (3…) — Script Hash
Dust Limit

The minimum payment amount is 546 satoshis (Bitcoin dust limit). Payments below this threshold are rejected.

Integration
import { ExactBtcScheme } from '@t402/btc/exact/client';
import { registerExactBtcScheme } from '@t402/btc/exact/server';
 
// Client — sign PSBTs
const btcClient = new ExactBtcScheme(btcSigner);
client.register('bip122:000000000019d6689c085ae165831e93', btcClient);
 
// Server — accept BTC payments
registerExactBtcScheme(server, {});
Signer Interface

Clients implement the ClientBtcSigner interface to sign PSBTs:

type ClientBtcSigner interface {
    // SignPsbt signs a PSBT and returns the base64-encoded signed PSBT
    SignPsbt(psbt string) (string, error)
 
    // GetAddress returns the signer's Bitcoin address
    GetAddress() string
 
    // GetPublicKey returns the signer's public key as hex
    GetPublicKey() string
}

Facilitators implement FacilitatorBtcSigner to verify and broadcast:

type FacilitatorBtcSigner interface {
    GetAddresses() []string
    VerifyPsbt(ctx context.Context, signedPsbt, expectedPayTo, expectedAmount string) (valid bool, reason string, payer string, err error)
    BroadcastPsbt(ctx context.Context, signedPsbt string) (txID string, err error)
    WaitForConfirmation(ctx context.Context, txID string, confirmations int) (confirmed bool, blockHash string, confs int, err error)
}
Lightning Network (BOLT11)

Lightning payments use BOLT11 invoices. The server provides a BOLT11 invoice, the client pays it and returns the preimage as proof of payment.

Payment Flow
  1. Server returns 402 with network: "lightning:mainnet" and a BOLT11 invoice in extra.bolt11Invoice
  2. Client pays the BOLT11 invoice via their Lightning node
  3. Client receives the preimage and payment hash
  4. Client submits preimage + payment hash as the payment payload
  5. Facilitator looks up the payment hash to verify settlement
  6. Payment confirmed instantly
Integration
import { LightningScheme } from '@t402/btc/lightning/client';
import { registerLightningScheme } from '@t402/btc/lightning/server';
 
// Client — pay BOLT11 invoices
const lnClient = new LightningScheme(lightningSigner);
client.register('lightning:mainnet', lnClient);
 
// Server — generate BOLT11 invoices
registerLightningScheme(server, { invoiceGenerator });
Lightning Signer Interface
type ClientLightningSigner interface {
    // PayInvoice pays a BOLT11 invoice and returns the preimage and payment hash
    PayInvoice(bolt11 string) (preimage string, paymentHash string, err error)
 
    // GetNodePubKey returns the Lightning node's public key as hex
    GetNodePubKey() string
}
BOLT11 Invoice Formats
PrefixNetwork
lnbcBitcoin Mainnet
lntbBitcoin Testnet
lnbcrtBitcoin Regtest
Payload Types
PSBT Payload
{
  "t402Version": 2,
  "payload": {
    "signedPsbt": "cHNidP8BAH..."
  },
  "accepted": {
    "scheme": "exact",
    "network": "bip122:000000000019d6689c085ae165831e93",
    "asset": "BTC",
    "amount": "100000",
    "payTo": "bc1q..."
  }
}
Lightning Payload
{
  "t402Version": 2,
  "payload": {
    "paymentHash": "abc123...",
    "preimage": "def456...",
    "bolt11Invoice": "lnbc10u1p..."
  },
  "accepted": {
    "scheme": "exact",
    "network": "lightning:mainnet",
    "asset": "BTC",
    "amount": "10000",
    "payTo": "02abc..."
  }
}
SDK Support
SDKOn-chain (PSBT)Lightning (BOLT11)
TypeScript (@t402/btc)Client, Server, FacilitatorClient, Server, Facilitator
Go (mechanisms/btc)Client, Server, FacilitatorClient
Python (schemes.btc)Client, Server, FacilitatorClient, Server
Java (io.t402.schemes.btc)Client, Server, FacilitatorClient, Facilitator
Server-Side Route Configuration
Go Server with Bitcoin
routes := t402http.RoutesConfig{
    "GET /api/data": {
        Accepts: t402http.PaymentOptions{
            {Scheme: "exact", PayTo: "bc1q...", Price: "10000", Network: btc.BtcMainnetCAIP2},
        },
        Description: "Data endpoint accepting BTC",
        MimeType:    "application/json",
    },
}
⚠️

Bitcoin amounts are specified in satoshis (1 BTC = 100,000,000 satoshis). The minimum payment amount is 546 satoshis (dust limit).

Accepting Both BTC and EVM
routes := t402http.RoutesConfig{
    "GET /api/data": {
        Accepts: t402http.PaymentOptions{
            {Scheme: "exact", PayTo: "bc1q...", Price: "10000", Network: btc.BtcMainnetCAIP2},
            {Scheme: "exact", PayTo: "0x...", Price: "$0.01", Network: "eip155:8453"},
        },
    },
}

Testnets

Testing T402 integration on testnet networks before production deployment.

Sandbox Facilitator — Use sandbox.t402.io as your testnet facilitator. No API key required. Supports 7 testnets with magic test addresses for deterministic testing. See the interactive playground.

Why Use Testnets?
  • Free tokens - No real funds required
  • Safe testing - No financial risk
  • Same behavior - Identical to mainnet
  • Debug easily - Block explorers available
EVM Testnets
ChainNetwork IDFaucet
Sepoliaeip155:11155111sepoliafaucet.com
Base Sepoliaeip155:84532base.org/faucet
Arbitrum Sepoliaeip155:421614faucet.arbitrum.io
Optimism Sepoliaeip155:11155420faucet.optimism.io
Ink Sepoliaeip155:763373faucet.ink.xyz
Berachain bArtioeip155:80084faucet.berachain.com
Unichain Sepoliaeip155:1301faucet.unichain.org
RPC Endpoints
const testnetRpcs = {
  'eip155:11155111': 'https://rpc.sepolia.org',
  'eip155:84532': 'https://sepolia.base.org',
  'eip155:421614': 'https://sepolia-rollup.arbitrum.io/rpc',
  'eip155:11155420': 'https://sepolia.optimism.io',
};
Configuration Example
// testnet-config.ts
const testnetRoutes = {
  '/api/test/*': {
    accepts: [
      {
        scheme: 'exact',
        network: 'eip155:84532', // Base Sepolia
        payTo: '0xYourTestAddress',
        price: '$0.001',
      },
    ],
  },
};
TON Testnet
PropertyValue
Network IDton:testnet
RPChttps://testnet.toncenter.com/api/v2/jsonRPC
Faucet@testgiver_ton_bot
Jetton MasterkQD0GKBM8ZbryVk2aESmzfU6b9b_8era_IkvBSELujFZPsyy
const tonTestnetConfig = {
  network: 'ton:testnet',
  jettonMaster: 'kQD0GKBM8ZbryVk2aESmzfU6b9b_8era_IkvBSELujFZPsyy',
  rpcUrl: 'https://testnet.toncenter.com/api/v2/jsonRPC',
};
TRON Testnets
TestnetNetwork IDRPCFaucet
Niletron:nilehttps://nile.trongrid.ionileex.io/faucet
Shastatron:shastahttps://api.shasta.trongrid.ioshasta.tronscan.org

Test USDT (Nile): TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf

Solana Devnet
PropertyValue
Network IDsolana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
RPChttps://api.devnet.solana.com
Faucetsolana airdrop 1 (CLI)
Test USDC Mint4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU
NEAR Testnet
PropertyValue
Network IDnear:testnet
RPChttps://rpc.testnet.near.org
Faucetnear.org/wallet
Test USDTusdt.fakes.testnet
const nearTestnetConfig = {
  network: 'near:testnet',
  rpcUrl: 'https://rpc.testnet.near.org',
  tokenContract: 'usdt.fakes.testnet',
};
Aptos Testnet
PropertyValue
Network IDaptos:2
RPChttps://fullnode.testnet.aptoslabs.com/v1
Faucetaptoslabs.com/faucet
Tezos Ghostnet
PropertyValue
Network IDtezos:NetXnHfVqm9iesp
RPChttps://ghostnet.tezos.marigold.dev
Faucetfaucet.ghostnet.teznet.xyz
Polkadot Westend
PropertyValue
Network IDpolkadot:e143f23803ac50e8f6f8e62695d1ce9e
Asset ID1984
Faucetfaucet.polkadot.io
Stacks Testnet
PropertyValue
Network IDstacks:2147483648
RPChttps://api.testnet.hiro.so
Faucetexplorer.hiro.so/faucet
Cosmos Testnet (Noble Grand)
PropertyValue
Network IDcosmos:grand-1
RPChttps://rpc.testnet.noble.strange.love
RESThttps://api.testnet.noble.strange.love
TokenUSDC (uusdc)
Testing Best Practices
1. Environment Variables
# .env.test
NODE_ENV=test
T402_NETWORK=eip155:84532
T402_RPC_URL=https://sepolia.base.org
T402_PAY_TO=0xYourTestAddress
T402_FACILITATOR_URL=https://facilitator.t402.io
2. Conditional Configuration
const isTestnet = process.env.NODE_ENV === 'test';
 
const config = {
  network: isTestnet ? 'eip155:84532' : 'eip155:8453',
  facilitator: 'https://facilitator.t402.io', // Same for both
};
3. Integration Tests
import { describe, it, expect } from 'vitest';
import { t402Client } from '@t402/core/client';
 
describe('T402 Integration', () => {
  it('should complete payment flow', async () => {
    const client = new t402Client();
    // ... setup with testnet
 
    const response = await client.fetch('https://api.example.com/test');
    expect(response.ok).toBe(true);
  });
});
4. Faucet Automation
// scripts/fund-test-wallet.ts
async function fundWallet(address: string, network: string) {
  switch (network) {
    case 'eip155:84532':
      // Base Sepolia faucet
      await requestBaseSepolia(address);
      break;
    case 'ton:testnet':
      console.log('Use @testgiver_ton_bot on Telegram');
      break;
    // ... other networks
  }
}
Facilitator Testnet Support

The public facilitator supports all testnets:

# Check supported networks
curl -s https://facilitator.t402.io/supported | jq '.kinds[] | select(.network | contains("testnet") or contains("sepolia"))'

The facilitator service handles both mainnet and testnet transactions. No separate testnet facilitator needed.


Comparison Matrix

This section provides a comprehensive comparison of all supported blockchain mechanisms across T402 SDKs.

Mechanism Support
MechanismSchemeToken StandardTypeScriptGoPythonJava
EVM (25 chains)exactEIP-3009
EVM (legacy)exact-legacyERC-20 approve
EVMuptoEIP-2612 permit
SolanaexactSPL Token
SolanauptoSPL Token approve
TONexactJetton (TEP-74)
TONuptoJetton approve
TRONexactTRC-20
TRONuptoTRC-20 approve
NEARexact-directNEP-141
NEARuptoNEP-141 approve
Aptosexact-directFungible Asset
Tezosexact-directFA2 (TZIP-12)
Polkadotexact-directAsset Hub
Stacksexact-directSIP-010
Cosmosexact-directBank MsgSend
StellarexactSoroban SEP-41
Choosing a Scheme

T402 supports three payment schemes. Choose based on your use case:

exact

Best for: Fixed-price resources, one-time payments

The client signs an off-chain authorization. The facilitator executes the transfer on-chain. Supported on EVM (via EIP-3009), Solana, TON, TRON, and Stellar.

Client signs → Facilitator settles on-chain
exact-direct

Best for: Chains without off-chain authorization standards

The client executes the transfer directly on-chain, then submits the transaction hash as proof. Used on NEAR, Aptos, Tezos, Polkadot, Stacks, and Cosmos.

Client transfers on-chain → Submits tx hash → Facilitator verifies
upto

Best for: Usage-based billing, metered APIs, streaming

The client pre-authorizes a maximum amount. The server charges only what is consumed. Currently supported on EVM (EIP-2612 permit), Solana, TON, TRON, and NEAR.

Client authorizes max → Server tracks usage → Facilitator settles actual amount
Choosing a Mechanism

Use this decision tree to pick the right mechanism:

  1. What blockchain does your user have funds on?

    • Ethereum, Arbitrum, Base, Optimism, or other EVM → Use @t402/evm
    • Solana → Use @t402/svm
    • TON → Use @t402/ton
    • TRON → Use @t402/tron
    • NEAR → Use @t402/near
    • Aptos → Use @t402/aptos
    • Tezos → Use @t402/tezos
    • Polkadot → Use @t402/polkadot
    • Stacks → Use @t402/stacks
    • Cosmos/Noble → Use @t402/cosmos
    • Stellar → Use @t402/stellar
  2. Do you need usage-based billing?

    • Yes → Use the upto scheme (available on EVM, Solana, TON, TRON, NEAR)
    • No → Use exact (EVM/Solana/TON/TRON) or exact-direct (all others)
  3. Do you need to accept payments from multiple chains?

    • Yes → Register multiple mechanisms with your server and use @t402/wdk-bridge for cross-chain bridging
    • No → Use a single mechanism package
HTTP Framework Support
FrameworkTypeScriptGoPythonJava
Express
Next.js
Hono
Fastify
Gin
Echo
Chi
net/http
FastAPI
Flask
Django
Starlette
Spring
Servlet
WebFlux
Micronaut
JAX-RS
SDK Versions
SDKVersionRegistry
TypeScript2.9.0npm
Go1.13.1pkg.go.dev
Python1.13.1PyPI
Java1.13.1Maven Central