API Reference@t402/evm

@t402/evm

EVM blockchain support for T402 with EIP-3009 gasless transfers, ERC-4337 account abstraction, and LayerZero USDT0 bridging.

Installation

pnpm add @t402/evm

Schemes

ExactEvmScheme

The primary EVM payment scheme using EIP-3009 transferWithAuthorization.

Client

import { ExactEvmScheme, toClientEvmSigner } from '@t402/evm';
import { privateKeyToAccount } from 'viem/accounts';
 
const account = privateKeyToAccount(PRIVATE_KEY);
const signer = toClientEvmSigner(account);
 
const scheme = ExactEvmScheme.client({
  signer,
  network: 'eip155:8453' // Base
});

Server

const scheme = ExactEvmScheme.server({
  rpcUrl: 'https://mainnet.base.org',
  network: 'eip155:8453'
});

Facilitator

const scheme = ExactEvmScheme.facilitator({
  signer: facilitatorSigner,
  rpcUrl: 'https://mainnet.base.org',
  network: 'eip155:8453'
});

ExactLegacyEvmScheme

For legacy tokens (like USDT on Ethereum) that don’t support EIP-3009.

import { ExactLegacyEvmClientScheme } from '@t402/evm';
 
const scheme = ExactLegacyEvmClientScheme({
  signer,
  network: 'eip155:1' // Ethereum mainnet
});

Signers

toClientEvmSigner

Creates a client signer from a viem account.

import { toClientEvmSigner } from '@t402/evm';
import { privateKeyToAccount } from 'viem/accounts';
 
const account = privateKeyToAccount('0x...');
const signer = toClientEvmSigner(account);

ClientEvmSigner Interface

interface ClientEvmSigner {
  address: `0x${string}`;
  signTypedData: (params: SignTypedDataParams) => Promise<`0x${string}`>;
}

toFacilitatorEvmSigner

Creates a facilitator signer with transaction capabilities.

import { toFacilitatorEvmSigner } from '@t402/evm';
 
const signer = toFacilitatorEvmSigner(account, walletClient);

Token Configuration

Token Addresses

import {
  USDT0_ADDRESSES,
  USDC_ADDRESSES,
  USDT_LEGACY_ADDRESSES
} from '@t402/evm';
 
// USDT0 on Base
const usdt0Base = USDT0_ADDRESSES['eip155:8453'];
// 0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee

Token Registry

import { TOKEN_REGISTRY, getTokenConfig } from '@t402/evm';
 
const config = getTokenConfig('eip155:8453', 'USDT0');
// { address: '0x...', decimals: 6, symbol: 'USDT0', supportsEIP3009: true }

Utility Functions

import {
  getNetworkTokens,
  getDefaultToken,
  supportsEIP3009,
  getUsdt0Networks
} from '@t402/evm';
 
// Get all tokens on Base
const tokens = getNetworkTokens('eip155:8453');
 
// Get default token for a network
const defaultToken = getDefaultToken('eip155:8453');
 
// Check EIP-3009 support
const hasGasless = supportsEIP3009('eip155:8453', '0x...');
 
// Get networks with USDT0
const networks = getUsdt0Networks(); // ['eip155:8453', 'eip155:42161', ...]

ERC-4337 Account Abstraction

Gasless payments using ERC-4337 smart accounts.

UserOpBuilder

Builds ERC-4337 user operations.

import { createUserOpBuilder } from '@t402/evm';
 
const builder = createUserOpBuilder({
  entryPoint: ENTRYPOINT_V07_ADDRESS,
  chainId: 8453,
  smartAccountAddress: '0x...'
});
 
const userOp = await builder.buildUserOp({
  to: recipientAddress,
  data: transferData,
  value: 0n
});

BundlerClient

Submits user operations to bundlers.

import { createBundlerClient } from '@t402/evm';
 
const bundler = createBundlerClient({
  url: 'https://bundler.example.com',
  chainId: 8453
});
 
// Get gas estimate
const gas = await bundler.estimateUserOperationGas(userOp);
 
// Send operation
const hash = await bundler.sendUserOperation(userOp);
 
// Wait for receipt
const receipt = await bundler.waitForUserOperationReceipt(hash);

PaymasterClient

Sponsors gas fees for user operations.

import { createPaymasterClient, PaymasterType } from '@t402/evm';
 
const paymaster = createPaymasterClient({
  url: 'https://paymaster.example.com',
  chainId: 8453,
  type: PaymasterType.VERIFYING
});
 
// Get sponsored operation
const sponsored = await paymaster.sponsorUserOperation(userOp, {
  token: USDT0_ADDRESS
});

GaslessT402Client

High-level client for gasless T402 payments.

import { createGaslessT402Client } from '@t402/evm';
 
const client = createGaslessT402Client({
  smartAccountAddress: '0x...',
  signer: eoaSigner,
  bundlerUrl: 'https://bundler.example.com',
  paymasterUrl: 'https://paymaster.example.com',
  chainId: 8453
});
 
// Make gasless payment
const result = await client.pay({
  to: merchantAddress,
  amount: 1000000n, // 1 USDT0
  token: USDT0_ADDRESS
});

Constants

import {
  ENTRYPOINT_V07_ADDRESS,
  ENTRYPOINT_V06_ADDRESS,
  DEFAULT_GAS_LIMITS
} from '@t402/evm';

LayerZero Bridge

Cross-chain USDT0 bridging via LayerZero OFT.

Usdt0Bridge

import { createUsdt0Bridge } from '@t402/evm';
 
const bridge = createUsdt0Bridge(signer, 'eip155:42161'); // From Arbitrum
 
// Get quote
const quote = await bridge.quote({
  toChain: 'eip155:8453', // To Base
  amount: 100000000n,     // 100 USDT0
  recipient: '0x...'
});
 
console.log('Native fee:', quote.nativeFee);
console.log('Estimated time:', quote.estimatedTime);
 
// Execute bridge
const result = await bridge.send({
  toChain: 'eip155:8453',
  amount: 100000000n,
  recipient: '0x...'
});
 
console.log('Tx hash:', result.txHash);
console.log('Message GUID:', result.messageGuid);

LayerZeroScanClient

Track cross-chain message status.

import { createLayerZeroScanClient } from '@t402/evm';
 
const scan = createLayerZeroScanClient();
 
// Get message status
const message = await scan.getMessage(messageGuid);
console.log('Status:', message.status); // INFLIGHT, CONFIRMING, DELIVERED
 
// Wait for delivery
const delivered = await scan.waitForDelivery(messageGuid, {
  timeout: 600000,  // 10 minutes
  pollInterval: 5000
});

CrossChainPaymentRouter

Automatic routing for cross-chain payments.

import { createCrossChainPaymentRouter } from '@t402/evm';
 
const router = createCrossChainPaymentRouter(signer, 'eip155:42161');
 
// Check if routing is possible
if (router.canRoute('eip155:42161', 'eip155:8453')) {
  const result = await router.routePayment({
    toChain: 'eip155:8453',
    amount: 50000000n,
    recipient: '0x...'
  });
}

Bridge Constants

import {
  LAYERZERO_ENDPOINT_IDS,
  USDT0_OFT_ADDRESSES,
  getBridgeableChains,
  supportsBridging
} from '@t402/evm';
 
// Check bridge support
const canBridge = supportsBridging('eip155:8453'); // true
 
// Get all bridgeable chains
const chains = getBridgeableChains();
// ['eip155:1', 'eip155:42161', 'eip155:8453', ...]

Types

ExactEvmPayloadV2

interface ExactEvmPayloadV2 {
  signature: `0x${string}`;
  authorization: {
    from: `0x${string}`;
    to: `0x${string}`;
    value: string;
    validAfter: string;
    validBefore: string;
    nonce: `0x${string}`;
  };
}

UserOperation

interface UserOperation {
  sender: `0x${string}`;
  nonce: bigint;
  initCode: `0x${string}`;
  callData: `0x${string}`;
  callGasLimit: bigint;
  verificationGasLimit: bigint;
  preVerificationGas: bigint;
  maxFeePerGas: bigint;
  maxPriorityFeePerGas: bigint;
  paymasterAndData: `0x${string}`;
  signature: `0x${string}`;
}

BridgeResult

interface BridgeResult {
  txHash: `0x${string}`;
  messageGuid: `0x${string}`;
  amountSent: bigint;
  amountToReceive: bigint;
  fromChain: string;
  toChain: string;
  estimatedTime: number;
}

Supported Networks

NetworkChain IDCAIP-2USDT0Bridge
Ethereum1eip155:1YesYes
Arbitrum42161eip155:42161YesYes
Base8453eip155:8453YesYes
Optimism10eip155:10YesNo
Polygon137eip155:137YesNo
Ink57073eip155:57073YesYes
Berachain80094eip155:80094YesYes
Unichain130eip155:130YesYes