@dexterai/x402 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.cjs +10 -2
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +4 -4
- package/dist/adapters/index.d.ts +4 -4
- package/dist/adapters/index.js +10 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/client/index.cjs +17 -5
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +4 -4
- package/dist/client/index.d.ts +4 -4
- package/dist/client/index.js +17 -5
- package/dist/client/index.js.map +1 -1
- package/dist/{evm-Df3cPUz6.d.cts → evm-C-eaz9sr.d.cts} +2 -2
- package/dist/{evm-DwBtG9OF.d.ts → evm-ClaLqigp.d.ts} +2 -2
- package/dist/react/index.cjs +19 -7
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +19 -7
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/{types-D3H1rG5o.d.cts → types-CikZVHR8.d.cts} +1 -1
- package/dist/{types-C7R908oZ.d.ts → types-DZ7Sn3wM.d.cts} +5 -3
- package/dist/{types-C7R908oZ.d.cts → types-DZ7Sn3wM.d.ts} +5 -3
- package/dist/{types-Bj70xvur.d.ts → types-F9CX8Ris.d.ts} +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/{x402-client-BZP1Tm25.d.cts → x402-client-CTJ4cZKb.d.cts} +1 -1
- package/dist/{x402-client-1Q7rm4nL.d.ts → x402-client-CzkL9xtM.d.ts} +1 -1
- package/package.json +1 -1
package/dist/adapters/index.cjs
CHANGED
|
@@ -126,7 +126,11 @@ var init_solana = __esm({
|
|
|
126
126
|
const url = rpcUrl || this.getDefaultRpcUrl(accept.network);
|
|
127
127
|
const connection = new import_web3.Connection(url, "confirmed");
|
|
128
128
|
const userPubkey = new import_web3.PublicKey(wallet.publicKey.toBase58());
|
|
129
|
-
const { payTo, asset,
|
|
129
|
+
const { payTo, asset, extra } = accept;
|
|
130
|
+
const amount = accept.amount || accept.maxAmountRequired;
|
|
131
|
+
if (!amount) {
|
|
132
|
+
throw new Error("Missing amount in payment requirements");
|
|
133
|
+
}
|
|
130
134
|
if (!extra?.feePayer) {
|
|
131
135
|
throw new Error("Missing feePayer in payment requirements");
|
|
132
136
|
}
|
|
@@ -356,7 +360,11 @@ var init_evm = __esm({
|
|
|
356
360
|
if (!wallet.address) {
|
|
357
361
|
throw new Error("Wallet not connected");
|
|
358
362
|
}
|
|
359
|
-
const { payTo, asset,
|
|
363
|
+
const { payTo, asset, extra } = accept;
|
|
364
|
+
const amount = accept.amount || accept.maxAmountRequired;
|
|
365
|
+
if (!amount) {
|
|
366
|
+
throw new Error("Missing amount in payment requirements");
|
|
367
|
+
}
|
|
360
368
|
this.log("Building EVM transaction:", {
|
|
361
369
|
from: wallet.address,
|
|
362
370
|
to: payTo,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/solana.ts","../../src/adapters/evm.ts","../../src/adapters/index.ts"],"sourcesContent":["/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.mainnet-beta.solana.com',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields\n const { payTo, asset, amount, extra } = accept;\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ETHEREUM_MAINNET = 'eip155:1';\nexport const ARBITRUM_ONE = 'eip155:42161';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ETHEREUM_MAINNET]: 1,\n [ARBITRUM_ONE]: 42161,\n};\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://mainnet.base.org',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n};\n\n/**\n * USDC addresses by chain (for reference)\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, amount, extra } = accept;\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n // Generate a random nonce (32 bytes hex)\n const nonce = '0x' + [...Array(32)]\n .map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, '0'))\n .join('') as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n","/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n ARBITRUM_ONE,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n const { createSolanaAdapter } = require('./solana');\n const { createEvmAdapter } = require('./evm');\n return [\n createSolanaAdapter({ verbose }),\n createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS","createSolanaAdapter","createEvmAdapter"]}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/solana.ts","../../src/adapters/evm.ts","../../src/adapters/index.ts"],"sourcesContent":["/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.mainnet-beta.solana.com',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields (amount or maxAmountRequired for x402 spec compatibility)\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ETHEREUM_MAINNET = 'eip155:1';\nexport const ARBITRUM_ONE = 'eip155:42161';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ETHEREUM_MAINNET]: 1,\n [ARBITRUM_ONE]: 42161,\n};\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://mainnet.base.org',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n};\n\n/**\n * USDC addresses by chain (for reference)\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n // Generate a random nonce (32 bytes hex)\n const nonce = '0x' + [...Array(32)]\n .map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, '0'))\n .join('') as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n","/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n ARBITRUM_ONE,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n const { createSolanaAdapter } = require('./solana');\n const { createEvmAdapter } = require('./evm');\n return [\n createSolanaAdapter({ verbose }),\n createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS","createSolanaAdapter","createEvmAdapter"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { C as ChainAdapter } from '../types-
|
|
2
|
-
export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-
|
|
3
|
-
export { A as ARBITRUM_ONE, B as BASE_MAINNET, h as BASE_SEPOLIA, j as ETHEREUM_MAINNET, E as EvmAdapter, k as EvmWallet, d as SOLANA_DEVNET, S as SOLANA_MAINNET, e as SOLANA_TESTNET, b as SolanaAdapter, f as SolanaWallet, a as createEvmAdapter, c as createSolanaAdapter, g as isEvmWallet, i as isSolanaWallet } from '../evm-
|
|
4
|
-
import '../types-
|
|
1
|
+
import { C as ChainAdapter } from '../types-CikZVHR8.cjs';
|
|
2
|
+
export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-CikZVHR8.cjs';
|
|
3
|
+
export { A as ARBITRUM_ONE, B as BASE_MAINNET, h as BASE_SEPOLIA, j as ETHEREUM_MAINNET, E as EvmAdapter, k as EvmWallet, d as SOLANA_DEVNET, S as SOLANA_MAINNET, e as SOLANA_TESTNET, b as SolanaAdapter, f as SolanaWallet, a as createEvmAdapter, c as createSolanaAdapter, g as isEvmWallet, i as isSolanaWallet } from '../evm-C-eaz9sr.cjs';
|
|
4
|
+
import '../types-DZ7Sn3wM.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Create all default adapters
|
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { C as ChainAdapter } from '../types-
|
|
2
|
-
export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-
|
|
3
|
-
export { A as ARBITRUM_ONE, B as BASE_MAINNET, h as BASE_SEPOLIA, j as ETHEREUM_MAINNET, E as EvmAdapter, k as EvmWallet, d as SOLANA_DEVNET, S as SOLANA_MAINNET, e as SOLANA_TESTNET, b as SolanaAdapter, f as SolanaWallet, a as createEvmAdapter, c as createSolanaAdapter, g as isEvmWallet, i as isSolanaWallet } from '../evm-
|
|
4
|
-
import '../types-
|
|
1
|
+
import { C as ChainAdapter } from '../types-F9CX8Ris.js';
|
|
2
|
+
export { A as AdapterConfig, B as BalanceInfo, G as GenericWallet, S as SignedTransaction, W as WalletSet } from '../types-F9CX8Ris.js';
|
|
3
|
+
export { A as ARBITRUM_ONE, B as BASE_MAINNET, h as BASE_SEPOLIA, j as ETHEREUM_MAINNET, E as EvmAdapter, k as EvmWallet, d as SOLANA_DEVNET, S as SOLANA_MAINNET, e as SOLANA_TESTNET, b as SolanaAdapter, f as SolanaWallet, a as createEvmAdapter, c as createSolanaAdapter, g as isEvmWallet, i as isSolanaWallet } from '../evm-ClaLqigp.js';
|
|
4
|
+
import '../types-DZ7Sn3wM.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Create all default adapters
|
package/dist/adapters/index.js
CHANGED
|
@@ -138,7 +138,11 @@ var init_solana = __esm({
|
|
|
138
138
|
const url = rpcUrl || this.getDefaultRpcUrl(accept.network);
|
|
139
139
|
const connection = new Connection(url, "confirmed");
|
|
140
140
|
const userPubkey = new PublicKey(wallet.publicKey.toBase58());
|
|
141
|
-
const { payTo, asset,
|
|
141
|
+
const { payTo, asset, extra } = accept;
|
|
142
|
+
const amount = accept.amount || accept.maxAmountRequired;
|
|
143
|
+
if (!amount) {
|
|
144
|
+
throw new Error("Missing amount in payment requirements");
|
|
145
|
+
}
|
|
142
146
|
if (!extra?.feePayer) {
|
|
143
147
|
throw new Error("Missing feePayer in payment requirements");
|
|
144
148
|
}
|
|
@@ -368,7 +372,11 @@ var init_evm = __esm({
|
|
|
368
372
|
if (!wallet.address) {
|
|
369
373
|
throw new Error("Wallet not connected");
|
|
370
374
|
}
|
|
371
|
-
const { payTo, asset,
|
|
375
|
+
const { payTo, asset, extra } = accept;
|
|
376
|
+
const amount = accept.amount || accept.maxAmountRequired;
|
|
377
|
+
if (!amount) {
|
|
378
|
+
throw new Error("Missing amount in payment requirements");
|
|
379
|
+
}
|
|
372
380
|
this.log("Building EVM transaction:", {
|
|
373
381
|
from: wallet.address,
|
|
374
382
|
to: payTo,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/solana.ts","../../src/adapters/evm.ts","../../src/adapters/index.ts"],"sourcesContent":["/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.mainnet-beta.solana.com',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields\n const { payTo, asset, amount, extra } = accept;\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ETHEREUM_MAINNET = 'eip155:1';\nexport const ARBITRUM_ONE = 'eip155:42161';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ETHEREUM_MAINNET]: 1,\n [ARBITRUM_ONE]: 42161,\n};\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://mainnet.base.org',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n};\n\n/**\n * USDC addresses by chain (for reference)\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, amount, extra } = accept;\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n // Generate a random nonce (32 bytes hex)\n const nonce = '0x' + [...Array(32)]\n .map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, '0'))\n .join('') as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n","/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n ARBITRUM_ONE,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n const { createSolanaAdapter } = require('./solana');\n const { createEvmAdapter } = require('./evm');\n return [\n createSolanaAdapter({ verbose }),\n createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS","createSolanaAdapter","createEvmAdapter"]}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/solana.ts","../../src/adapters/evm.ts","../../src/adapters/index.ts"],"sourcesContent":["/**\n * Solana Chain Adapter\n *\n * Implements the ChainAdapter interface for Solana networks.\n * Handles transaction building, signing, and balance queries.\n */\n\nimport {\n PublicKey,\n Connection,\n TransactionMessage,\n VersionedTransaction,\n ComputeBudgetProgram,\n type TransactionInstruction,\n} from '@solana/web3.js';\nimport {\n getAssociatedTokenAddress,\n getAccount,\n createTransferCheckedInstruction,\n getMint,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from '@solana/spl-token';\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for Solana\n */\nexport const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\nexport const SOLANA_DEVNET = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\nexport const SOLANA_TESTNET = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z';\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [SOLANA_MAINNET]: 'https://api.mainnet-beta.solana.com',\n [SOLANA_DEVNET]: 'https://api.devnet.solana.com',\n [SOLANA_TESTNET]: 'https://api.testnet.solana.com',\n};\n\n/**\n * Dexter policy-safe compute budget settings\n */\nconst DEFAULT_COMPUTE_UNIT_LIMIT = 12_000;\nconst DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 1;\n\n/**\n * Solana wallet interface (compatible with @solana/wallet-adapter)\n */\nexport interface SolanaWallet {\n publicKey: { toBase58(): string } | null;\n signTransaction<T>(tx: T): Promise<T>;\n}\n\n/**\n * Check if an object is a valid Solana wallet\n */\nexport function isSolanaWallet(wallet: unknown): wallet is SolanaWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'publicKey' in w &&\n 'signTransaction' in w &&\n typeof w.signTransaction === 'function'\n );\n}\n\n/**\n * Solana Chain Adapter\n */\nexport class SolanaAdapter implements ChainAdapter {\n readonly name = 'Solana';\n readonly networks = [SOLANA_MAINNET, SOLANA_DEVNET, SOLANA_TESTNET];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:solana]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle both exact CAIP-2 and legacy formats\n if (this.networks.includes(network)) return true;\n // Legacy format support\n if (network === 'solana') return true;\n if (network === 'solana-devnet') return true;\n if (network === 'solana-testnet') return true;\n // Check if it starts with 'solana:'\n if (network.startsWith('solana:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n // Check custom config first\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n // Check defaults\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy networks\n if (network === 'solana') return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n if (network === 'solana-devnet') return DEFAULT_RPC_URLS[SOLANA_DEVNET];\n if (network === 'solana-testnet') return DEFAULT_RPC_URLS[SOLANA_TESTNET];\n // Default to mainnet\n return DEFAULT_RPC_URLS[SOLANA_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isSolanaWallet(wallet)) return null;\n return wallet.publicKey?.toBase58() ?? null;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isSolanaWallet(wallet)) return false;\n return wallet.publicKey !== null;\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isSolanaWallet(wallet) || !wallet.publicKey) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n const mintPubkey = new PublicKey(accept.asset);\n\n try {\n // Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n const programId =\n mintInfo?.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const ata = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n\n const account = await getAccount(connection, ata, undefined, programId);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(account.amount) / Math.pow(10, decimals);\n } catch {\n // Token account doesn't exist\n return 0;\n }\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isSolanaWallet(wallet)) {\n throw new Error('Invalid Solana wallet');\n }\n if (!wallet.publicKey) {\n throw new Error('Wallet not connected');\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n const connection = new Connection(url, 'confirmed');\n const userPubkey = new PublicKey(wallet.publicKey.toBase58());\n\n // Extract required fields (amount or maxAmountRequired for x402 spec compatibility)\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n if (!extra?.feePayer) {\n throw new Error('Missing feePayer in payment requirements');\n }\n // Note: decimals is optional - we fetch from mint on-chain if not provided\n\n const feePayerPubkey = new PublicKey(extra.feePayer);\n const mintPubkey = new PublicKey(asset);\n const destinationPubkey = new PublicKey(payTo);\n\n this.log('Building transaction:', {\n from: userPubkey.toBase58(),\n to: payTo,\n amount,\n asset,\n feePayer: extra.feePayer,\n });\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // 1. ComputeBudget: Set compute unit limit\n instructions.push(\n ComputeBudgetProgram.setComputeUnitLimit({\n units: DEFAULT_COMPUTE_UNIT_LIMIT,\n })\n );\n\n // 2. ComputeBudget: Set compute unit price\n instructions.push(\n ComputeBudgetProgram.setComputeUnitPrice({\n microLamports: DEFAULT_COMPUTE_UNIT_PRICE_MICROLAMPORTS,\n })\n );\n\n // 3. Determine token program\n const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');\n if (!mintInfo) {\n throw new Error(`Token mint ${asset} not found`);\n }\n\n const programId =\n mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58()\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n // Fetch mint to get decimals (required for TransferChecked)\n const mint = await getMint(connection, mintPubkey, undefined, programId);\n if (typeof extra?.decimals === 'number' && mint.decimals !== extra.decimals) {\n this.log(\n `Decimals mismatch: requirements say ${extra.decimals}, mint says ${mint.decimals}`\n );\n }\n\n // Derive Associated Token Accounts\n const sourceAta = await getAssociatedTokenAddress(\n mintPubkey,\n userPubkey,\n false,\n programId\n );\n const destinationAta = await getAssociatedTokenAddress(\n mintPubkey,\n destinationPubkey,\n false,\n programId\n );\n\n // Verify source ATA exists\n const sourceAtaInfo = await connection.getAccountInfo(sourceAta, 'confirmed');\n if (!sourceAtaInfo) {\n throw new Error(\n `No token account found for ${asset}. Please ensure you have USDC in your wallet.`\n );\n }\n\n // Verify destination ATA exists\n const destAtaInfo = await connection.getAccountInfo(destinationAta, 'confirmed');\n if (!destAtaInfo) {\n throw new Error(\n `Seller token account not found. The seller (${payTo}) must have a USDC account.`\n );\n }\n\n // 4. TransferChecked instruction\n const amountBigInt = BigInt(amount);\n instructions.push(\n createTransferCheckedInstruction(\n sourceAta,\n mintPubkey,\n destinationAta,\n userPubkey,\n amountBigInt,\n mint.decimals,\n [],\n programId\n )\n );\n\n // Get recent blockhash\n const { blockhash } = await connection.getLatestBlockhash('confirmed');\n\n // Compile to V0 message (feePayer is facilitator)\n const message = new TransactionMessage({\n payerKey: feePayerPubkey,\n recentBlockhash: blockhash,\n instructions,\n }).compileToV0Message();\n\n // Create and sign transaction\n const transaction = new VersionedTransaction(message);\n const signedTx = await wallet.signTransaction(transaction);\n\n this.log('Transaction signed successfully');\n\n return {\n serialized: Buffer.from(signedTx.serialize()).toString('base64'),\n };\n }\n}\n\n/**\n * Create a Solana adapter instance\n */\nexport function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter {\n return new SolanaAdapter(config);\n}\n\n\n\n","/**\n * EVM Chain Adapter\n *\n * Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)\n * Uses EIP-712 typed data signing for x402 v2 payments.\n */\n\nimport type { ChainAdapter, AdapterConfig, SignedTransaction } from './types';\nimport type { PaymentAccept } from '../types';\n\n/**\n * CAIP-2 network identifiers for EVM chains\n */\nexport const BASE_MAINNET = 'eip155:8453';\nexport const BASE_SEPOLIA = 'eip155:84532';\nexport const ETHEREUM_MAINNET = 'eip155:1';\nexport const ARBITRUM_ONE = 'eip155:42161';\n\n/**\n * Chain IDs by CAIP-2 network\n */\nconst CHAIN_IDS: Record<string, number> = {\n [BASE_MAINNET]: 8453,\n [BASE_SEPOLIA]: 84532,\n [ETHEREUM_MAINNET]: 1,\n [ARBITRUM_ONE]: 42161,\n};\n\n/**\n * Default RPC URLs\n */\nconst DEFAULT_RPC_URLS: Record<string, string> = {\n [BASE_MAINNET]: 'https://mainnet.base.org',\n [BASE_SEPOLIA]: 'https://sepolia.base.org',\n [ETHEREUM_MAINNET]: 'https://eth.llamarpc.com',\n [ARBITRUM_ONE]: 'https://arb1.arbitrum.io/rpc',\n};\n\n/**\n * USDC addresses by chain (for reference)\n */\nexport const USDC_ADDRESSES: Record<string, string> = {\n [BASE_MAINNET]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n [ETHEREUM_MAINNET]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n [ARBITRUM_ONE]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n};\n\n/**\n * EVM wallet interface (compatible with wagmi, ethers, viem)\n */\nexport interface EvmWallet {\n /** Wallet address */\n address: string;\n /** Chain ID currently connected to */\n chainId?: number;\n /**\n * Sign typed data (EIP-712)\n * This is the primary signing method for x402 EVM payments\n */\n signTypedData?(params: {\n domain: Record<string, unknown>;\n types: Record<string, unknown[]>;\n primaryType: string;\n message: Record<string, unknown>;\n }): Promise<string>;\n /**\n * Alternative: Send transaction directly\n * Used if signTypedData is not available\n */\n sendTransaction?(params: {\n to: string;\n data: string;\n value?: bigint;\n }): Promise<string>;\n}\n\n/**\n * Check if an object is a valid EVM wallet\n */\nexport function isEvmWallet(wallet: unknown): wallet is EvmWallet {\n if (!wallet || typeof wallet !== 'object') return false;\n const w = wallet as Record<string, unknown>;\n return (\n 'address' in w &&\n typeof w.address === 'string' &&\n w.address.startsWith('0x')\n );\n}\n\n// ERC20 balanceOf function selector: 0x70a08231\n\n/**\n * EVM Chain Adapter\n */\nexport class EvmAdapter implements ChainAdapter {\n readonly name = 'EVM';\n readonly networks = [BASE_MAINNET, BASE_SEPOLIA, ETHEREUM_MAINNET, ARBITRUM_ONE];\n\n private config: AdapterConfig;\n private log: (...args: unknown[]) => void;\n\n constructor(config: AdapterConfig = {}) {\n this.config = config;\n this.log = config.verbose\n ? console.log.bind(console, '[x402:evm]')\n : () => {};\n }\n\n canHandle(network: string): boolean {\n // Handle exact CAIP-2\n if (this.networks.includes(network)) return true;\n // Legacy format\n if (network === 'base') return true;\n if (network === 'ethereum') return true;\n if (network === 'arbitrum') return true;\n // Check if it starts with 'eip155:'\n if (network.startsWith('eip155:')) return true;\n return false;\n }\n\n getDefaultRpcUrl(network: string): string {\n if (this.config.rpcUrls?.[network]) {\n return this.config.rpcUrls[network];\n }\n if (DEFAULT_RPC_URLS[network]) {\n return DEFAULT_RPC_URLS[network];\n }\n // Normalize legacy\n if (network === 'base') return DEFAULT_RPC_URLS[BASE_MAINNET];\n if (network === 'ethereum') return DEFAULT_RPC_URLS[ETHEREUM_MAINNET];\n if (network === 'arbitrum') return DEFAULT_RPC_URLS[ARBITRUM_ONE];\n return DEFAULT_RPC_URLS[BASE_MAINNET];\n }\n\n getAddress(wallet: unknown): string | null {\n if (!isEvmWallet(wallet)) return null;\n return wallet.address;\n }\n\n isConnected(wallet: unknown): boolean {\n if (!isEvmWallet(wallet)) return false;\n return !!wallet.address;\n }\n\n private getChainId(network: string): number {\n if (CHAIN_IDS[network]) return CHAIN_IDS[network];\n // Try to extract from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainIdStr = network.split(':')[1];\n return parseInt(chainIdStr, 10);\n }\n // Defaults\n if (network === 'base') return 8453;\n if (network === 'ethereum') return 1;\n if (network === 'arbitrum') return 42161;\n return 8453; // Default to Base\n }\n\n async getBalance(\n accept: PaymentAccept,\n wallet: unknown,\n rpcUrl?: string\n ): Promise<number> {\n if (!isEvmWallet(wallet) || !wallet.address) {\n return 0;\n }\n\n const url = rpcUrl || this.getDefaultRpcUrl(accept.network);\n\n try {\n // Use eth_call to check ERC20 balance\n const data = this.encodeBalanceOf(wallet.address);\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_call',\n params: [\n {\n to: accept.asset,\n data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = (await response.json()) as { error?: unknown; result?: string };\n if (result.error || !result.result) {\n return 0;\n }\n\n const balance = BigInt(result.result);\n const decimals = accept.extra?.decimals ?? 6;\n return Number(balance) / Math.pow(10, decimals);\n } catch {\n return 0;\n }\n }\n\n private encodeBalanceOf(address: string): string {\n // Function selector for balanceOf(address)\n const selector = '0x70a08231';\n // Pad address to 32 bytes\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, '0');\n return selector + paddedAddress;\n }\n\n async buildTransaction(\n accept: PaymentAccept,\n wallet: unknown,\n _rpcUrl?: string\n ): Promise<SignedTransaction> {\n if (!isEvmWallet(wallet)) {\n throw new Error('Invalid EVM wallet');\n }\n if (!wallet.address) {\n throw new Error('Wallet not connected');\n }\n\n const { payTo, asset, extra } = accept;\n const amount = accept.amount || accept.maxAmountRequired;\n if (!amount) {\n throw new Error('Missing amount in payment requirements');\n }\n\n this.log('Building EVM transaction:', {\n from: wallet.address,\n to: payTo,\n amount,\n asset,\n network: accept.network,\n });\n\n // For x402 v2 EVM payments, we use EIP-712 typed data signing\n // The facilitator will execute the transfer on behalf of the user\n\n const chainId = this.getChainId(accept.network);\n\n // Build the EIP-712 typed data\n // This matches what Dexter's facilitator expects\n const domain = {\n name: extra?.name ?? 'USD Coin',\n version: extra?.version ?? '2',\n chainId: BigInt(chainId),\n verifyingContract: asset as `0x${string}`,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n // Generate a random nonce (32 bytes hex)\n const nonce = '0x' + [...Array(32)]\n .map(() => Math.floor(Math.random() * 256).toString(16).padStart(2, '0'))\n .join('') as `0x${string}`;\n\n const now = Math.floor(Date.now() / 1000);\n \n // Authorization object - values as strings for JSON, BigInts for signing\n const authorization = {\n from: wallet.address,\n to: payTo,\n value: amount, // string\n validAfter: String(now - 600), // 10 minutes before (matching upstream)\n validBefore: String(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n // Message for signing uses BigInt values\n const message = {\n from: wallet.address,\n to: payTo,\n value: BigInt(amount),\n validAfter: BigInt(now - 600),\n validBefore: BigInt(now + (accept.maxTimeoutSeconds || 60)),\n nonce,\n };\n\n if (!wallet.signTypedData) {\n throw new Error('Wallet does not support signTypedData (EIP-712)');\n }\n\n const signature = await wallet.signTypedData({\n domain: domain as Record<string, unknown>,\n types: types as Record<string, unknown[]>,\n primaryType: 'TransferWithAuthorization',\n message: message as Record<string, unknown>,\n });\n\n this.log('EIP-712 signature obtained');\n\n // Payload structure matches upstream @x402/evm exactly\n const payload = {\n authorization,\n signature,\n };\n\n return {\n serialized: JSON.stringify(payload),\n signature,\n };\n }\n}\n\n/**\n * Create an EVM adapter instance\n */\nexport function createEvmAdapter(config?: AdapterConfig): EvmAdapter {\n return new EvmAdapter(config);\n}\n\n","/**\n * Chain Adapters\n *\n * x402 v2 is designed to be chain-agnostic. Each adapter handles\n * the specifics of transaction building and signing for its chain.\n *\n * @example\n * ```typescript\n * import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';\n *\n * const adapters = [\n * createSolanaAdapter(),\n * createEvmAdapter(),\n * ];\n *\n * // Find adapter for a network\n * const adapter = adapters.find(a => a.canHandle('eip155:8453'));\n * ```\n */\n\n// Types\nexport type {\n ChainAdapter,\n AdapterConfig,\n SignedTransaction,\n GenericWallet,\n WalletSet,\n BalanceInfo,\n} from './types';\n\n// Solana\nexport {\n SolanaAdapter,\n createSolanaAdapter,\n isSolanaWallet,\n SOLANA_MAINNET,\n SOLANA_DEVNET,\n SOLANA_TESTNET,\n} from './solana';\nexport type { SolanaWallet } from './solana';\n\n// EVM\nexport {\n EvmAdapter,\n createEvmAdapter,\n isEvmWallet,\n BASE_MAINNET,\n BASE_SEPOLIA,\n ETHEREUM_MAINNET,\n ARBITRUM_ONE,\n} from './evm';\nexport type { EvmWallet } from './evm';\n\n/**\n * Create all default adapters\n */\nexport function createDefaultAdapters(verbose = false) {\n const { createSolanaAdapter } = require('./solana');\n const { createEvmAdapter } = require('./evm');\n return [\n createSolanaAdapter({ verbose }),\n createEvmAdapter({ verbose }),\n ];\n}\n\n/**\n * Find adapter that can handle a network\n */\nexport function findAdapter(\n adapters: import('./types').ChainAdapter[],\n network: string\n): import('./types').ChainAdapter | undefined {\n return adapters.find(adapter => adapter.canHandle(network));\n}\n\n\n\n"],"mappings":"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","names":["DEFAULT_RPC_URLS","createSolanaAdapter","createEvmAdapter"]}
|
package/dist/client/index.cjs
CHANGED
|
@@ -117,7 +117,11 @@ var init_solana = __esm({
|
|
|
117
117
|
const url = rpcUrl || this.getDefaultRpcUrl(accept.network);
|
|
118
118
|
const connection = new import_web3.Connection(url, "confirmed");
|
|
119
119
|
const userPubkey = new import_web3.PublicKey(wallet.publicKey.toBase58());
|
|
120
|
-
const { payTo, asset,
|
|
120
|
+
const { payTo, asset, extra } = accept;
|
|
121
|
+
const amount = accept.amount || accept.maxAmountRequired;
|
|
122
|
+
if (!amount) {
|
|
123
|
+
throw new Error("Missing amount in payment requirements");
|
|
124
|
+
}
|
|
121
125
|
if (!extra?.feePayer) {
|
|
122
126
|
throw new Error("Missing feePayer in payment requirements");
|
|
123
127
|
}
|
|
@@ -336,7 +340,11 @@ var init_evm = __esm({
|
|
|
336
340
|
if (!wallet.address) {
|
|
337
341
|
throw new Error("Wallet not connected");
|
|
338
342
|
}
|
|
339
|
-
const { payTo, asset,
|
|
343
|
+
const { payTo, asset, extra } = accept;
|
|
344
|
+
const amount = accept.amount || accept.maxAmountRequired;
|
|
345
|
+
if (!amount) {
|
|
346
|
+
throw new Error("Missing amount in payment requirements");
|
|
347
|
+
}
|
|
340
348
|
this.log("Building EVM transaction:", {
|
|
341
349
|
from: wallet.address,
|
|
342
350
|
to: payTo,
|
|
@@ -549,16 +557,20 @@ function createX402Client(config) {
|
|
|
549
557
|
"Payment option missing decimals - provide in extra or use a known stablecoin"
|
|
550
558
|
);
|
|
551
559
|
}
|
|
552
|
-
|
|
560
|
+
const paymentAmount = accept.amount || accept.maxAmountRequired;
|
|
561
|
+
if (!paymentAmount) {
|
|
562
|
+
throw new X402Error("missing_amount", "Payment option missing amount");
|
|
563
|
+
}
|
|
564
|
+
if (maxAmountAtomic && BigInt(paymentAmount) > BigInt(maxAmountAtomic)) {
|
|
553
565
|
throw new X402Error(
|
|
554
566
|
"amount_exceeds_max",
|
|
555
|
-
`Payment amount ${
|
|
567
|
+
`Payment amount ${paymentAmount} exceeds maximum ${maxAmountAtomic}`
|
|
556
568
|
);
|
|
557
569
|
}
|
|
558
570
|
const rpcUrl = getRpcUrl(accept.network, adapter);
|
|
559
571
|
log("Checking balance...");
|
|
560
572
|
const balance = await adapter.getBalance(accept, wallet, rpcUrl);
|
|
561
|
-
const requiredAmount = Number(
|
|
573
|
+
const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
|
|
562
574
|
if (balance < requiredAmount) {
|
|
563
575
|
const network = adapter.name === "EVM" ? "Base" : "Solana";
|
|
564
576
|
throw new X402Error(
|