@dcentralab/d402-client 0.1.0

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.
@@ -0,0 +1,859 @@
1
+ import { Account } from 'viem/accounts';
2
+ import { Hash } from 'viem';
3
+
4
+ /**
5
+ * Type definitions for D402 payment protocol
6
+ */
7
+
8
+ /**
9
+ * Supported blockchain networks
10
+ */
11
+ type SupportedNetwork = 'mainnet' | 'sepolia' | 'base' | 'polygon';
12
+ /**
13
+ * D402 Client configuration
14
+ */
15
+ interface D402Config {
16
+ /** Viem account for signing payments */
17
+ account: Account;
18
+ /** Blockchain network */
19
+ network: SupportedNetwork;
20
+ /** Maximum payment amount in wei (smallest token unit) */
21
+ maxPaymentAmount: bigint;
22
+ /** Token contract address (defaults to USDC if not provided) */
23
+ tokenAddress?: `0x${string}`;
24
+ /** Payment validity window in seconds (default: 300) */
25
+ validityWindowSeconds?: number;
26
+ }
27
+ /**
28
+ * EIP-712 domain for signature verification
29
+ */
30
+ interface EIP712Domain {
31
+ name: string;
32
+ version: string;
33
+ chainId: number;
34
+ verifyingContract: `0x${string}`;
35
+ }
36
+ /**
37
+ * Payment requirement from 402 response
38
+ *
39
+ * Matches Python: PaymentRequirements (types.py lines 97-108)
40
+ */
41
+ interface PaymentRequirement {
42
+ /** D402 protocol version */
43
+ d402Version?: number;
44
+ /** Payment scheme (exact or range) */
45
+ scheme: 'exact' | 'range';
46
+ /** Network identifier */
47
+ network: string;
48
+ /** Maximum amount required (in wei/smallest unit) */
49
+ maxAmountRequired: string;
50
+ /** Recipient address */
51
+ payTo: `0x${string}`;
52
+ /** Token contract address */
53
+ asset: `0x${string}`;
54
+ /** Resource identifier (API path) */
55
+ resource?: string;
56
+ /** Description of the service */
57
+ description?: string;
58
+ /** MIME type of response */
59
+ mimeType?: string;
60
+ /** Output schema definition */
61
+ outputSchema?: any;
62
+ /** Maximum timeout in seconds */
63
+ maxTimeoutSeconds?: number;
64
+ /** Additional EIP-712 domain info */
65
+ extra?: {
66
+ name: string;
67
+ version: string;
68
+ chainId: number;
69
+ };
70
+ }
71
+ /**
72
+ * Payment authorization details
73
+ */
74
+ interface PaymentAuthorization {
75
+ /** Sender address */
76
+ from: `0x${string}`;
77
+ /** Recipient address */
78
+ to: `0x${string}`;
79
+ /** Payment amount (wei/smallest unit) */
80
+ value: string;
81
+ /** Valid after timestamp */
82
+ validAfter: string;
83
+ /** Valid before timestamp */
84
+ validBefore: string;
85
+ /** Unique nonce */
86
+ nonce: `0x${string}`;
87
+ /** Request path/resource */
88
+ requestPath: string;
89
+ }
90
+ /**
91
+ * Signed payment ready to send
92
+ */
93
+ interface SignedPayment {
94
+ /** D402 protocol version */
95
+ d402Version: number;
96
+ /** Payment scheme */
97
+ scheme: string;
98
+ /** Network identifier */
99
+ network: string;
100
+ /** Payment payload */
101
+ payload: {
102
+ /** EIP-712 signature */
103
+ signature: `0x${string}`;
104
+ /** Authorization details */
105
+ authorization: PaymentAuthorization;
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Payment requirements selection logic
111
+ */
112
+
113
+ /**
114
+ * Options for selecting payment requirements
115
+ */
116
+ interface PaymentSelectorOptions {
117
+ /** Filter by network (e.g., "base-mainnet") */
118
+ network?: string;
119
+ /** Filter by payment scheme (default: "exact") */
120
+ scheme?: string;
121
+ /** Maximum allowed payment amount in base units */
122
+ maxAmount?: bigint;
123
+ /** Preferred network (will try this first) */
124
+ preferredNetwork?: string;
125
+ /** Preferred token address */
126
+ preferredToken?: string;
127
+ }
128
+ /**
129
+ * Select payment requirement from a list based on filters and preferences
130
+ *
131
+ * This function implements the same logic as Python's default_payment_requirements_selector
132
+ *
133
+ * @param requirements - List of accepted payment requirements from 402 response
134
+ * @param options - Selection options and filters
135
+ * @returns Selected payment requirement
136
+ *
137
+ * @throws {UnsupportedSchemeError} If no matching scheme found
138
+ * @throws {PaymentAmountExceededError} If payment exceeds max amount
139
+ *
140
+ * @example
141
+ * const selected = selectPaymentRequirement(requirements, {
142
+ * scheme: 'exact',
143
+ * network: 'base-mainnet',
144
+ * maxAmount: 1000000n
145
+ * })
146
+ */
147
+ declare function selectPaymentRequirement(requirements: PaymentRequirement[], options?: PaymentSelectorOptions): PaymentRequirement;
148
+ /**
149
+ * Custom payment selector function type
150
+ */
151
+ type PaymentSelector = (requirements: PaymentRequirement[], options?: PaymentSelectorOptions) => PaymentRequirement;
152
+ /**
153
+ * Create a custom payment selector with default options
154
+ *
155
+ * @param defaultOptions - Default options to apply
156
+ * @returns Custom selector function
157
+ *
158
+ * @example
159
+ * const selector = createPaymentSelector({
160
+ * preferredNetwork: 'base-mainnet',
161
+ * maxAmount: 1000000n
162
+ * })
163
+ *
164
+ * const selected = selector(requirements, { scheme: 'exact' })
165
+ */
166
+ declare function createPaymentSelector(defaultOptions: PaymentSelectorOptions): PaymentSelector;
167
+ /**
168
+ * Sort payment requirements by preference
169
+ * Useful for UI display or debugging
170
+ *
171
+ * @param requirements - List of requirements
172
+ * @param preferredNetwork - Preferred network name
173
+ * @returns Sorted list (preferred first)
174
+ */
175
+ declare function sortPaymentRequirements(requirements: PaymentRequirement[], preferredNetwork?: string): PaymentRequirement[];
176
+
177
+ /**
178
+ * D402 Client - Main client class for handling HTTP 402 payments
179
+ *
180
+ * Matches Python implementation: IATP/src/traia_iatp/d402/clients/base.py d402Client
181
+ */
182
+
183
+ /**
184
+ * D402 Client configuration.
185
+ *
186
+ * Matches Python: d402Client.__init__ parameters (base.py lines 66-72)
187
+ */
188
+ interface D402ClientConfig {
189
+ /** Operator account with private key for signing payments (EOA) */
190
+ operatorAccount: Account;
191
+ /**
192
+ * Consumer's IATPWallet contract address.
193
+ * If not provided, uses operator_account.address for testing.
194
+ */
195
+ walletAddress?: `0x${string}`;
196
+ /**
197
+ * Optional safety limit for maximum payment amount per request in base units.
198
+ *
199
+ * WARNING: This is a simple numeric comparison and does NOT account for:
200
+ * - Different tokens (USDC vs TRAIA vs others) - amounts are compared directly
201
+ * - Token decimals - ensure maxValue uses the same decimals as expected tokens
202
+ * - Exchange rates - this is not a USD limit, it's a token amount limit
203
+ *
204
+ * Each endpoint can have different payment requirements (amount and token),
205
+ * but this limit applies to all requests. Set it based on your most expensive
206
+ * expected payment in the token's base units.
207
+ *
208
+ * If undefined, no limit is enforced (not recommended for production).
209
+ */
210
+ maxValue?: bigint;
211
+ /**
212
+ * Optional custom selector for payment requirements.
213
+ * If not provided, uses default selector that picks first "exact" scheme.
214
+ */
215
+ paymentRequirementsSelector?: PaymentSelector;
216
+ /**
217
+ * Optional network filter for payment selection.
218
+ * Only select requirements matching this network.
219
+ */
220
+ networkFilter?: string;
221
+ /**
222
+ * Optional scheme filter for payment selection.
223
+ * Defaults to "exact".
224
+ */
225
+ schemeFilter?: string;
226
+ }
227
+ /**
228
+ * D402 Client for handling HTTP 402 Payment Required responses.
229
+ *
230
+ * Matches Python: d402Client class (base.py lines 63-219)
231
+ *
232
+ * This client automatically:
233
+ * 1. Detects HTTP 402 responses
234
+ * 2. Parses payment requirements
235
+ * 3. Selects appropriate payment option
236
+ * 4. Signs payment with EIP-712
237
+ * 5. Retries request with X-Payment header
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * import { D402Client } from '@iatp/d402-client'
242
+ * import { privateKeyToAccount } from 'viem/accounts'
243
+ *
244
+ * const operatorAccount = privateKeyToAccount('0x...')
245
+ *
246
+ * const client = new D402Client({
247
+ * operatorAccount,
248
+ * walletAddress: '0xUserIATPWallet...',
249
+ * maxValue: 1000000n // 1 USDC max
250
+ * })
251
+ *
252
+ * const response = await client.fetch('http://api.example.com/analyze', {
253
+ * method: 'POST',
254
+ * body: JSON.stringify({ text: 'Analyze this' })
255
+ * })
256
+ *
257
+ * const data = await response.json()
258
+ * ```
259
+ */
260
+ declare class D402Client {
261
+ private readonly operatorAccount;
262
+ private readonly walletAddress;
263
+ private readonly maxValue?;
264
+ private readonly paymentRequirementsSelector;
265
+ private readonly networkFilter?;
266
+ private readonly schemeFilter;
267
+ /**
268
+ * Create a new D402 Client.
269
+ *
270
+ * Matches Python: d402Client.__init__ (base.py lines 66-95)
271
+ *
272
+ * @param config - Client configuration
273
+ */
274
+ constructor(config: D402ClientConfig);
275
+ /**
276
+ * Select payment requirement from list of options.
277
+ *
278
+ * Matches Python: select_payment_requirements (base.py lines 152-174)
279
+ *
280
+ * @param requirements - List of payment requirements from 402 response
281
+ * @returns Selected payment requirement
282
+ */
283
+ selectPaymentRequirement(requirements: PaymentRequirement[]): PaymentRequirement;
284
+ /**
285
+ * Get the wallet address used for payments.
286
+ *
287
+ * @returns IATPWallet contract address or operator EOA address
288
+ */
289
+ getWalletAddress(): `0x${string}`;
290
+ /**
291
+ * Get the operator account used for signing.
292
+ *
293
+ * @returns Operator account
294
+ */
295
+ getOperatorAccount(): Account;
296
+ /**
297
+ * Get the maximum payment value limit.
298
+ *
299
+ * @returns Maximum value in base units, or undefined if no limit
300
+ */
301
+ getMaxValue(): bigint | undefined;
302
+ /**
303
+ * Fetch with automatic 402 payment handling.
304
+ *
305
+ * Matches Python: HttpxHooks.on_response() (httpx.py lines 33-117)
306
+ *
307
+ * Flow:
308
+ * 1. Make request without payment
309
+ * 2. If 402 response, parse payment requirements
310
+ * 3. Select appropriate payment option
311
+ * 4. Sign payment with EIP-712
312
+ * 5. Retry request with X-Payment header
313
+ * 6. Return final response
314
+ *
315
+ * @param url - URL to fetch
316
+ * @param init - Fetch options (method, headers, body, etc.)
317
+ * @returns Response object (after payment if 402)
318
+ *
319
+ * @example
320
+ * ```ts
321
+ * const client = new D402Client({ operatorAccount, walletAddress })
322
+ *
323
+ * const response = await client.fetch('http://api.example.com/analyze', {
324
+ * method: 'POST',
325
+ * headers: { 'Content-Type': 'application/json' },
326
+ * body: JSON.stringify({ text: 'Analyze this' })
327
+ * })
328
+ *
329
+ * const data = await response.json()
330
+ * ```
331
+ */
332
+ fetch(url: string, init?: RequestInit): Promise<Response>;
333
+ }
334
+
335
+ /**
336
+ * EIP-712 payment signing utilities
337
+ *
338
+ * Matches Python implementation: IATP/src/traia_iatp/d402/payment_signing.py
339
+ */
340
+
341
+ /**
342
+ * Sign a D402 payment using EIP-712 signature.
343
+ *
344
+ * Matches Python: sign_payment_header(operator_account, payment_requirements, header, wallet_address, request_path)
345
+ * (payment_signing.py lines 54-155)
346
+ *
347
+ * This creates a PullFundsForSettlement signature that matches IATPWallet.sol validation.
348
+ *
349
+ * @param params - Signing parameters
350
+ * @param params.operatorAccount - Operator account with private key for signing (EOA)
351
+ * @param params.paymentRequirement - Payment requirements from 402 response
352
+ * @param params.walletAddress - Consumer's IATPWallet contract address (optional, uses operator address if not provided)
353
+ * @param params.requestPath - API request path (optional, uses payment_requirements.resource if not provided)
354
+ * @returns Signed payment ready to encode and send
355
+ *
356
+ * @example
357
+ * ```ts
358
+ * const requirement = await parsePaymentRequirement(response)
359
+ * const signedPayment = await signD402Payment({
360
+ * operatorAccount: account,
361
+ * paymentRequirement: requirement,
362
+ * walletAddress: '0xUserWallet...'
363
+ * })
364
+ * const encoded = encodePayment(signedPayment)
365
+ * ```
366
+ */
367
+ declare function signD402Payment(params: {
368
+ operatorAccount: Account;
369
+ paymentRequirement: PaymentRequirement;
370
+ walletAddress?: `0x${string}`;
371
+ requestPath?: string;
372
+ d402Version?: number;
373
+ }): Promise<SignedPayment>;
374
+
375
+ /**
376
+ * Parse 402 payment requirements from HTTP responses
377
+ *
378
+ * Matches Python implementation: IATP/src/traia_iatp/d402/clients/httpx.py lines 64-66
379
+ * Response structure from: IATP/src/traia_iatp/d402/types.py d402PaymentRequiredResponse
380
+ */
381
+
382
+ /**
383
+ * Parse payment requirements from HTTP 402 response.
384
+ *
385
+ * Matches Python:
386
+ * data = response.json()
387
+ * payment_response = d402PaymentRequiredResponse(**data)
388
+ *
389
+ * The 402 response body contains payment requirements in camelCase JSON format.
390
+ *
391
+ * @param response - HTTP Response object with status 402
392
+ * @returns First payment requirement from accepts array
393
+ * @throws {Invalid402ResponseError} If response is not valid 402 or malformed
394
+ *
395
+ * @example
396
+ * ```ts
397
+ * const response = await fetch('http://api.example.com')
398
+ * if (response.status === 402) {
399
+ * const requirement = await parsePaymentRequirement(response)
400
+ * console.log(requirement.maxAmountRequired) // "10000"
401
+ * }
402
+ * ```
403
+ */
404
+ declare function parsePaymentRequirement(response: Response): Promise<PaymentRequirement>;
405
+
406
+ /**
407
+ * Base64 encoding/decoding for payment payloads
408
+ *
409
+ * Matches Python implementation: IATP/src/traia_iatp/d402/encoding.py
410
+ */
411
+
412
+ /**
413
+ * Encode a payment object to base64 string.
414
+ *
415
+ * This combines JSON serialization with base64 encoding.
416
+ * Matches Python: encode_payment(payment_payload: Dict[str, Any]) -> str
417
+ *
418
+ * @param payment - Payment object to encode
419
+ * @returns Base64 encoded payment string suitable for X-Payment header
420
+ *
421
+ * @example
422
+ * ```ts
423
+ * const payment = { d402Version: 1, scheme: 'exact', payload: {...} }
424
+ * const encoded = encodePayment(payment)
425
+ * // Use in header: { 'X-Payment': encoded }
426
+ * ```
427
+ */
428
+ declare function encodePayment(payment: SignedPayment): string;
429
+ /**
430
+ * Decode a base64 encoded payment string back to payment object.
431
+ *
432
+ * Matches Python: decode_payment(encoded_payment: str) -> Dict[str, Any]
433
+ *
434
+ * @param encodedPayment - Base64 encoded payment string
435
+ * @returns Decoded payment object
436
+ *
437
+ * @example
438
+ * ```ts
439
+ * const payment = decodePayment(encodedString)
440
+ * console.log(payment.d402Version) // 1
441
+ * ```
442
+ */
443
+ declare function decodePayment(encodedPayment: string): SignedPayment;
444
+
445
+ /**
446
+ * Utility functions for D402 payment processing
447
+ */
448
+
449
+ /**
450
+ * Parse a money string or number into atomic units (wei)
451
+ *
452
+ * @param amount - Amount as string (e.g., "$1.00", "1.5") or number
453
+ * @param decimals - Token decimals (e.g., 6 for USDC, 18 for ETH)
454
+ * @returns Amount in atomic units (wei)
455
+ *
456
+ * @example
457
+ * parseMoney("$1.00", 6) // Returns 1000000n (1 USDC in wei)
458
+ * parseMoney("0.5", 18) // Returns 500000000000000000n (0.5 ETH in wei)
459
+ */
460
+ declare function parseMoney(amount: string | number | bigint, decimals: number): bigint;
461
+ /**
462
+ * Format atomic units back to human-readable format
463
+ *
464
+ * @param amount - Amount in atomic units (wei)
465
+ * @param decimals - Token decimals
466
+ * @returns Formatted string
467
+ *
468
+ * @example
469
+ * formatMoney(1000000n, 6) // Returns "1.000000"
470
+ */
471
+ declare function formatMoney(amount: bigint, decimals: number): string;
472
+ /**
473
+ * Get USDC token address for a given network
474
+ *
475
+ * @param network - Network name
476
+ * @returns USDC token address
477
+ *
478
+ * @throws {UnsupportedNetworkError} If network is not supported
479
+ */
480
+ declare function getUsdcAddress(network: SupportedNetwork): `0x${string}`;
481
+ /**
482
+ * Get chain ID for a given network.
483
+ *
484
+ * Matches Python: get_chain_id(network: str) -> str (chains.py lines 10-21)
485
+ *
486
+ * Supports both network names and numeric chain IDs as strings.
487
+ *
488
+ * @param network - Network name or chain ID as string
489
+ * @returns Chain ID as number
490
+ *
491
+ * @throws {UnsupportedNetworkError} If network is not supported
492
+ *
493
+ * @example
494
+ * ```ts
495
+ * getChainId('sepolia') // Returns 11155111
496
+ * getChainId('11155111') // Returns 11155111 (passthrough)
497
+ * getChainId('base') // Returns 8453
498
+ * ```
499
+ */
500
+ declare function getChainId(network: string): number;
501
+ /**
502
+ * Find matching payment requirement from a list
503
+ *
504
+ * @param requirements - List of payment requirements
505
+ * @param scheme - Desired payment scheme (default: "exact")
506
+ * @param network - Desired network (optional)
507
+ * @returns Matching payment requirement or undefined
508
+ */
509
+ declare function findMatchingPaymentRequirement(requirements: PaymentRequirement[], scheme?: string, network?: string): PaymentRequirement | undefined;
510
+ /**
511
+ * Convert USD amount to USDC atomic units
512
+ *
513
+ * @param usdAmount - Amount in USD (e.g., "1.00" or 1.5)
514
+ * @param decimals - USDC decimals (default: 6)
515
+ * @returns Amount in USDC atomic units
516
+ *
517
+ * @example
518
+ * usdToUsdc("1.00") // Returns 1000000n
519
+ * usdToUsdc(1.5) // Returns 1500000n
520
+ */
521
+ declare function usdToUsdc(usdAmount: string | number, decimals?: number): bigint;
522
+ /**
523
+ * Generate a random nonce for payment authorization
524
+ *
525
+ * @returns Random 32-byte nonce as hex string
526
+ */
527
+ declare function generateNonce(): `0x${string}`;
528
+ /**
529
+ * Get current timestamp in seconds
530
+ *
531
+ * @returns Unix timestamp in seconds
532
+ */
533
+ declare function getCurrentTimestamp(): number;
534
+ /**
535
+ * Validate Ethereum address format
536
+ *
537
+ * @param address - Address to validate
538
+ * @returns True if valid Ethereum address
539
+ */
540
+ declare function isValidAddress(address: string): boolean;
541
+ /**
542
+ * Normalize Ethereum address to checksummed format
543
+ * Note: This is a simple lowercase normalization. For full checksum validation, use viem's getAddress()
544
+ *
545
+ * @param address - Address to normalize
546
+ * @returns Normalized address
547
+ */
548
+ declare function normalizeAddress(address: string): `0x${string}`;
549
+ /**
550
+ * Decode X-PAYMENT-RESPONSE header from server
551
+ *
552
+ * @param header - Base64 encoded payment response
553
+ * @returns Decoded payment response
554
+ *
555
+ * @example
556
+ * const response = decodePaymentResponse(responseHeader)
557
+ * console.log(response.success, response.transaction)
558
+ */
559
+ declare function decodePaymentResponse(header: string): {
560
+ success: boolean;
561
+ transaction?: string;
562
+ network?: string;
563
+ payer?: string;
564
+ message?: string;
565
+ };
566
+
567
+ /**
568
+ * Error classes for D402 payment protocol
569
+ */
570
+ /**
571
+ * Base error class for all payment-related errors
572
+ */
573
+ declare class PaymentError extends Error {
574
+ constructor(message: string);
575
+ }
576
+ /**
577
+ * Thrown when payment amount exceeds the configured maximum allowed value
578
+ */
579
+ declare class PaymentAmountExceededError extends PaymentError {
580
+ amount: bigint;
581
+ maxAmount: bigint;
582
+ tokenAddress?: string | undefined;
583
+ constructor(amount: bigint, maxAmount: bigint, tokenAddress?: string | undefined);
584
+ }
585
+ /**
586
+ * Thrown when request configuration is missing required fields
587
+ */
588
+ declare class MissingRequestConfigError extends PaymentError {
589
+ constructor(message: string);
590
+ }
591
+ /**
592
+ * Thrown when payment has already been attempted for a request
593
+ */
594
+ declare class PaymentAlreadyAttemptedError extends PaymentError {
595
+ constructor(message?: string);
596
+ }
597
+ /**
598
+ * Thrown when no supported payment scheme is found in payment requirements
599
+ */
600
+ declare class UnsupportedSchemeError extends PaymentError {
601
+ availableSchemes: string[];
602
+ constructor(availableSchemes: string[], message?: string);
603
+ }
604
+ /**
605
+ * Thrown when payment verification fails
606
+ */
607
+ declare class PaymentVerificationError extends PaymentError {
608
+ constructor(message: string);
609
+ }
610
+ /**
611
+ * Thrown when HTTP 402 response is malformed
612
+ */
613
+ declare class Invalid402ResponseError extends PaymentError {
614
+ constructor(message: string);
615
+ }
616
+ /**
617
+ * Thrown when network is not supported
618
+ */
619
+ declare class UnsupportedNetworkError extends PaymentError {
620
+ network: string;
621
+ constructor(network: string);
622
+ }
623
+
624
+ /**
625
+ * Network and token constants
626
+ */
627
+
628
+ /**
629
+ * Chain IDs for supported networks
630
+ */
631
+ declare const CHAIN_IDS: Record<SupportedNetwork, number>;
632
+ /**
633
+ * Network configuration
634
+ */
635
+ declare const NETWORKS: Record<SupportedNetwork, {
636
+ chainId: number;
637
+ name: string;
638
+ nativeCurrency: {
639
+ name: string;
640
+ symbol: string;
641
+ decimals: number;
642
+ };
643
+ }>;
644
+ /**
645
+ * Default USDC token addresses per network
646
+ */
647
+ declare const TOKEN_ADDRESSES: Record<SupportedNetwork, `0x${string}`>;
648
+ /**
649
+ * Default payment validity window (5 minutes)
650
+ */
651
+ declare const DEFAULT_VALIDITY_WINDOW_SECONDS = 300;
652
+ /**
653
+ * EIP-712 type definitions for PullFundsForSettlement
654
+ */
655
+ declare const EIP712_TYPES: {
656
+ readonly PullFundsForSettlement: readonly [{
657
+ readonly name: "wallet";
658
+ readonly type: "address";
659
+ }, {
660
+ readonly name: "provider";
661
+ readonly type: "address";
662
+ }, {
663
+ readonly name: "token";
664
+ readonly type: "address";
665
+ }, {
666
+ readonly name: "amount";
667
+ readonly type: "uint256";
668
+ }, {
669
+ readonly name: "deadline";
670
+ readonly type: "uint256";
671
+ }, {
672
+ readonly name: "requestPath";
673
+ readonly type: "string";
674
+ }];
675
+ };
676
+
677
+ /**
678
+ * Contract configuration and utilities for IATP.
679
+ *
680
+ * Matches Python implementation: IATP/src/traia_iatp/contracts/config.py
681
+ *
682
+ * Bundles contract ABIs and addresses directly in the package for reliable access.
683
+ */
684
+ /**
685
+ * Supported contract names.
686
+ *
687
+ * Matches Python: ContractName enum (config.py lines 16-21)
688
+ */
689
+ declare enum ContractName {
690
+ IATP_WALLET = "IATPWallet",
691
+ IATP_WALLET_FACTORY = "IATPWalletFactory",
692
+ IATP_SETTLEMENT_LAYER = "IATPSettlementLayer",
693
+ ROLE_MANAGER = "RoleManager"
694
+ }
695
+ /**
696
+ * Supported networks for contract deployments.
697
+ *
698
+ * Matches Python: SUPPORTED_NETWORKS (config.py line 25)
699
+ */
700
+ type SupportedContractNetwork = 'sepolia' | 'localhost';
701
+ /**
702
+ * Get contract address for a given network.
703
+ *
704
+ * Matches Python: get_contract_address(contract_name: str, network: str) -> Optional[str]
705
+ * (config.py lines 77-118)
706
+ *
707
+ * @param contractName - Name of the contract (use ContractName enum)
708
+ * @param network - Network name (default: "sepolia")
709
+ * @param useProxy - Use proxy address if true, implementation if false (default: true)
710
+ * @returns Contract address as hex string, or null if not found
711
+ *
712
+ * @example
713
+ * ```ts
714
+ * const factoryAddr = getContractAddress(ContractName.IATP_WALLET_FACTORY, 'sepolia')
715
+ * console.log(factoryAddr) // "0x15D83638E339a0f29283f6B93dC1bb90b8339078"
716
+ * ```
717
+ */
718
+ declare function getContractAddress(contractName: string | ContractName, network?: SupportedContractNetwork, useProxy?: boolean): string | null;
719
+ /**
720
+ * Get contract ABI for a given network.
721
+ *
722
+ * Matches Python: get_contract_abi(contract_name: str, network: str) -> Optional[List[dict]]
723
+ * (config.py lines 121-156)
724
+ *
725
+ * @param contractName - Name of the contract (use ContractName enum)
726
+ * @param network - Network name (default: "sepolia")
727
+ * @returns Contract ABI as array of objects, or null if not found
728
+ *
729
+ * @example
730
+ * ```ts
731
+ * const factoryAbi = getContractAbi(ContractName.IATP_WALLET_FACTORY, 'sepolia')
732
+ * console.log(factoryAbi.length) // Number of ABI entries
733
+ * ```
734
+ */
735
+ declare function getContractAbi(contractName: string | ContractName, network?: SupportedContractNetwork): any[] | null;
736
+ /**
737
+ * Get contract configuration (address and ABI) for a network.
738
+ *
739
+ * Matches Python: get_contract_config(network: str) from wallet_creator.py
740
+ *
741
+ * @param contractName - Name of the contract
742
+ * @param network - Network name (default: "sepolia")
743
+ * @returns Object with address and abi, or null if not found
744
+ *
745
+ * @example
746
+ * ```ts
747
+ * const config = getContractConfig(ContractName.IATP_WALLET_FACTORY, 'sepolia')
748
+ * if (config) {
749
+ * console.log(config.address)
750
+ * console.log(config.abi.length)
751
+ * }
752
+ * ```
753
+ */
754
+ declare function getContractConfig(contractName: string | ContractName, network?: SupportedContractNetwork): {
755
+ address: string;
756
+ abi: any[];
757
+ } | null;
758
+ /**
759
+ * Get all contract addresses for a network.
760
+ *
761
+ * @param network - Network name
762
+ * @returns Object with all contract addresses for the network
763
+ *
764
+ * @example
765
+ * ```ts
766
+ * const addresses = getAllContractAddresses('sepolia')
767
+ * console.log(addresses.IATPWalletFactory)
768
+ * ```
769
+ */
770
+ declare function getAllContractAddresses(network: SupportedContractNetwork): Record<string, string>;
771
+ /**
772
+ * Check if a contract is deployed on a network.
773
+ *
774
+ * @param contractName - Name of the contract
775
+ * @param network - Network name
776
+ * @returns True if contract exists on network
777
+ *
778
+ * @example
779
+ * ```ts
780
+ * if (isContractDeployed(ContractName.IATP_WALLET_FACTORY, 'sepolia')) {
781
+ * // Contract is available
782
+ * }
783
+ * ```
784
+ */
785
+ declare function isContractDeployed(contractName: string | ContractName, network: SupportedContractNetwork): boolean;
786
+
787
+ /**
788
+ * IATPWallet creation and management
789
+ *
790
+ * Matches Python implementation: IATP/src/traia_iatp/scripts/create_wallet.py
791
+ */
792
+
793
+ /**
794
+ * Result of wallet creation.
795
+ *
796
+ * Matches Python: create_wallet() return type (lines 138-147)
797
+ */
798
+ interface WalletCreationResult {
799
+ /** Address of the created IATPWallet contract */
800
+ walletAddress: `0x${string}`;
801
+ /** Owner address (who created it) */
802
+ ownerAddress: `0x${string}`;
803
+ /** Operator address (can sign payments) */
804
+ operatorAddress: `0x${string}`;
805
+ /** Operator private key (store securely!) */
806
+ operatorPrivateKey: `0x${string}`;
807
+ /** Transaction hash */
808
+ transactionHash: Hash;
809
+ /** Block number where wallet was created */
810
+ blockNumber: bigint;
811
+ /** Network where wallet was deployed */
812
+ network: string;
813
+ /** Chain ID */
814
+ chainId: number;
815
+ }
816
+ /**
817
+ * Create a new IATPWallet using IATPWalletFactory.
818
+ *
819
+ * Matches Python: create_wallet(owner_private_key, network, wait_confirmations)
820
+ * (create_wallet.py lines 37-149)
821
+ *
822
+ * This function:
823
+ * 1. Generates a new operator keypair
824
+ * 2. Calls IATPWalletFactory.createWallet(operatorAddress)
825
+ * 3. Waits for transaction confirmation
826
+ * 4. Extracts wallet address from WalletCreated event
827
+ * 5. Returns wallet info including operator keys
828
+ *
829
+ * @param params - Creation parameters
830
+ * @param params.ownerAccount - Owner's account (will own the wallet)
831
+ * @param params.network - Network to deploy on (default: "sepolia")
832
+ * @param params.rpcUrl - Custom RPC URL (optional)
833
+ * @param params.operatorPrivateKey - Use specific operator key instead of generating (optional)
834
+ * @returns Wallet creation result with addresses and keys
835
+ *
836
+ * @example
837
+ * ```ts
838
+ * import { createIATPWallet } from '@iatp/d402-client'
839
+ * import { privateKeyToAccount } from 'viem/accounts'
840
+ *
841
+ * const ownerAccount = privateKeyToAccount('0x...')
842
+ *
843
+ * const result = await createIATPWallet({
844
+ * ownerAccount,
845
+ * network: 'sepolia'
846
+ * })
847
+ *
848
+ * console.log('Wallet created:', result.walletAddress)
849
+ * console.log('Operator key:', result.operatorPrivateKey) // Store securely!
850
+ * ```
851
+ */
852
+ declare function createIATPWallet(params: {
853
+ ownerAccount: Account;
854
+ network?: 'sepolia' | 'localhost';
855
+ rpcUrl?: string;
856
+ operatorPrivateKey?: `0x${string}`;
857
+ }): Promise<WalletCreationResult>;
858
+
859
+ export { CHAIN_IDS, ContractName, D402Client, type D402ClientConfig, type D402Config, DEFAULT_VALIDITY_WINDOW_SECONDS, type EIP712Domain, EIP712_TYPES, Invalid402ResponseError, MissingRequestConfigError, NETWORKS, PaymentAlreadyAttemptedError, PaymentAmountExceededError, type PaymentAuthorization, PaymentError, type PaymentRequirement, type PaymentSelector, type PaymentSelectorOptions, PaymentVerificationError, type SignedPayment, type SupportedContractNetwork, type SupportedNetwork, TOKEN_ADDRESSES, UnsupportedNetworkError, UnsupportedSchemeError, type WalletCreationResult, createIATPWallet, createPaymentSelector, decodePayment, decodePaymentResponse, encodePayment, findMatchingPaymentRequirement, formatMoney, generateNonce, getAllContractAddresses, getChainId, getContractAbi, getContractAddress, getContractConfig, getCurrentTimestamp, getUsdcAddress, isContractDeployed, isValidAddress, normalizeAddress, parseMoney, parsePaymentRequirement, selectPaymentRequirement, signD402Payment, sortPaymentRequirements, usdToUsdc };