11import { config } from 'dotenv' ;
22import { x402Client , x402HTTPClient } from '@x402/core/client' ;
3+ import { toClientEvmSigner } from '@x402/evm' ;
4+ import { ExactEvmScheme } from '@x402/evm/exact/client' ;
35import { wrapFetchWithPayment } from '@x402/fetch' ;
46import {
57 CaveatType ,
@@ -12,7 +14,9 @@ import {
1214import { encodeDelegations } from '@metamask/smart-accounts-kit/utils' ;
1315import { x402Erc7710Client } from '@metamask/smart-accounts-kit-x402' ;
1416import {
17+ createPublicClient ,
1518 getAddress ,
19+ http ,
1620 type Hex ,
1721} from 'viem' ;
1822import { privateKeyToAccount } from 'viem/accounts' ;
@@ -23,12 +27,16 @@ config();
2327type CliConfig = {
2428 privateKey : Hex ;
2529 url : string ;
30+ paymentMethod : 'erc7710' | 'eip3009' ;
31+ rpcUrl ?: string ;
2632} ;
2733
2834function parseCliConfig ( ) : CliConfig {
2935 const args = process . argv . slice ( 2 ) ;
3036 const keyArgIndex = args . findIndex ( ( arg ) => arg === '--private-key' ) ;
3137 const urlArgIndex = args . findIndex ( ( arg ) => arg === '--url' ) ;
38+ const methodArgIndex = args . findIndex ( ( arg ) => arg === '--payment-method' ) ;
39+ const rpcUrlArgIndex = args . findIndex ( ( arg ) => arg === '--rpc-url' ) ;
3240
3341 const privateKeyFromArg =
3442 keyArgIndex >= 0 ? ( args [ keyArgIndex + 1 ] as Hex | undefined ) : undefined ;
@@ -44,7 +52,22 @@ function parseCliConfig(): CliConfig {
4452 const urlFromArg = urlArgIndex >= 0 ? args [ urlArgIndex + 1 ] : undefined ;
4553 const url = urlFromArg ?? process . env . X402_URL ?? 'http://localhost:4021/random' ;
4654
47- return { privateKey, url } ;
55+ const paymentMethodFromArg =
56+ methodArgIndex >= 0 ? args [ methodArgIndex + 1 ] : undefined ;
57+ const paymentMethod =
58+ paymentMethodFromArg ?? process . env . X402_PAYMENT_METHOD ?? 'erc7710' ;
59+
60+ if ( paymentMethod !== 'erc7710' && paymentMethod !== 'eip3009' ) {
61+ throw new Error (
62+ `Unsupported payment method "${ paymentMethod } ". Expected "erc7710" or "eip3009"` ,
63+ ) ;
64+ }
65+
66+ const rpcUrlFromArg =
67+ rpcUrlArgIndex >= 0 ? args [ rpcUrlArgIndex + 1 ] : undefined ;
68+ const rpcUrl = rpcUrlFromArg ?? process . env . X402_RPC_URL ?? process . env . RPC_URL ;
69+
70+ return { privateKey, url, paymentMethod, rpcUrl } ;
4871}
4972
5073function parseChainIdFromNetwork ( network : string ) : number {
@@ -64,8 +87,21 @@ function parseChainIdFromNetwork(network: string): number {
6487
6588
6689async function main ( ) {
67- const { privateKey, url } = parseCliConfig ( ) ;
90+ const { privateKey, url, paymentMethod , rpcUrl } = parseCliConfig ( ) ;
6891 const account = privateKeyToAccount ( privateKey ) ;
92+ const permit2Signer = ( ( ) => {
93+ if ( ! rpcUrl ) {
94+ return account ;
95+ }
96+
97+ const publicClient = createPublicClient ( {
98+ transport : http ( rpcUrl ) ,
99+ } ) ;
100+
101+ return toClientEvmSigner ( account , publicClient ) ;
102+ } ) ( ) ;
103+
104+ const exactEvmClient = new ExactEvmScheme ( permit2Signer ) ;
69105
70106 const erc7710Client = new x402Erc7710Client ( {
71107 delegationProvider : async ( requirements ) => {
@@ -114,10 +150,39 @@ async function main() {
114150 } ,
115151 } ) ;
116152
117- const httpClient = new x402HTTPClient ( new x402Client ( ) . register (
118- 'eip155:*' ,
119- erc7710Client
120- ) ) ;
153+ const selectedClient =
154+ paymentMethod === 'erc7710' ? erc7710Client : exactEvmClient ;
155+
156+ const coreClient = new x402Client ( )
157+ . register ( 'eip155:*' , selectedClient )
158+ . registerPolicy ( ( _x402Version , paymentRequirements ) => {
159+ const filtered = paymentRequirements . filter (
160+ ( requirements ) =>
161+ requirements . extra ?. assetTransferMethod === paymentMethod ,
162+ ) ;
163+
164+ if ( filtered . length > 0 ) {
165+ return filtered ;
166+ }
167+
168+ const availableMethods = [
169+ ...new Set (
170+ paymentRequirements
171+ . map ( ( requirements ) => requirements . extra ?. assetTransferMethod )
172+ . filter ( ( method ) : method is string => typeof method === 'string' ) ,
173+ ) ,
174+ ] ;
175+
176+ throw new Error (
177+ `Requested payment method "${ paymentMethod } " was not offered by the server. Available methods: ${
178+ availableMethods . length > 0
179+ ? availableMethods . join ( ', ' )
180+ : 'none'
181+ } `,
182+ ) ;
183+ } ) ;
184+
185+ const httpClient = new x402HTTPClient ( coreClient ) ;
121186
122187 const fetchWithPayment = wrapFetchWithPayment ( fetch , httpClient ) ;
123188
0 commit comments