@dcentralab/d402-client 0.2.0 → 0.2.2
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/README.md +128 -68
- package/dist/index.d.mts +92 -94
- package/dist/index.d.ts +92 -94
- package/dist/index.js +23 -4149
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -4150
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -6,9 +6,9 @@ import { Hash, Address } from 'viem';
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Supported blockchain networks
|
|
9
|
+
* Supported blockchain networks (where IATP contracts are deployed)
|
|
10
10
|
*/
|
|
11
|
-
type SupportedNetwork = '
|
|
11
|
+
type SupportedNetwork = 'sepolia';
|
|
12
12
|
/**
|
|
13
13
|
* D402 Client configuration
|
|
14
14
|
*/
|
|
@@ -34,9 +34,9 @@ interface EIP712Domain {
|
|
|
34
34
|
verifyingContract: `0x${string}`;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
* Payment requirement from 402 response
|
|
37
|
+
* Payment requirement from 402 response.
|
|
38
38
|
*
|
|
39
|
-
*
|
|
39
|
+
* Describes the payment details required by a 402-protected API.
|
|
40
40
|
*/
|
|
41
41
|
interface PaymentRequirement {
|
|
42
42
|
/** D402 protocol version */
|
|
@@ -128,7 +128,7 @@ interface PaymentSelectorOptions {
|
|
|
128
128
|
/**
|
|
129
129
|
* Select payment requirement from a list based on filters and preferences
|
|
130
130
|
*
|
|
131
|
-
* This function implements the same logic as
|
|
131
|
+
* This function implements the same logic as
|
|
132
132
|
*
|
|
133
133
|
* @param requirements - List of accepted payment requirements from 402 response
|
|
134
134
|
* @param options - Selection options and filters
|
|
@@ -177,20 +177,23 @@ declare function sortPaymentRequirements(requirements: PaymentRequirement[], pre
|
|
|
177
177
|
/**
|
|
178
178
|
* D402 Client - Main client class for handling HTTP 402 payments
|
|
179
179
|
*
|
|
180
|
-
* Matches Python implementation: IATP/src/traia_iatp/d402/clients/base.py d402Client
|
|
181
180
|
*/
|
|
182
181
|
|
|
183
182
|
/**
|
|
184
183
|
* D402 Client configuration.
|
|
185
184
|
*
|
|
186
|
-
*
|
|
185
|
+
* The client uses the user's wallet to sign payment authorizations for 402-protected APIs.
|
|
187
186
|
*/
|
|
188
187
|
interface D402ClientConfig {
|
|
189
|
-
/**
|
|
188
|
+
/**
|
|
189
|
+
* User's account for signing payments.
|
|
190
|
+
* Typically from wagmi: `walletClient.account`
|
|
191
|
+
*/
|
|
190
192
|
operatorAccount: Account;
|
|
191
193
|
/**
|
|
192
|
-
* IATPWallet contract address.
|
|
193
|
-
* If not provided, uses operatorAccount.address
|
|
194
|
+
* IATPWallet contract address (optional).
|
|
195
|
+
* If not provided, uses operatorAccount.address directly.
|
|
196
|
+
* Get from `createIATPWallet()` or `getWalletsByOwner()`.
|
|
194
197
|
*/
|
|
195
198
|
iatpWalletAddress?: `0x${string}`;
|
|
196
199
|
/**
|
|
@@ -227,8 +230,6 @@ interface D402ClientConfig {
|
|
|
227
230
|
/**
|
|
228
231
|
* D402 Client for handling HTTP 402 Payment Required responses.
|
|
229
232
|
*
|
|
230
|
-
* Matches Python: d402Client class (base.py lines 63-219)
|
|
231
|
-
*
|
|
232
233
|
* This client automatically:
|
|
233
234
|
* 1. Detects HTTP 402 responses
|
|
234
235
|
* 2. Parses payment requirements
|
|
@@ -267,15 +268,23 @@ declare class D402Client {
|
|
|
267
268
|
/**
|
|
268
269
|
* Create a new D402 Client.
|
|
269
270
|
*
|
|
270
|
-
* Matches Python: d402Client.__init__ (base.py lines 66-95)
|
|
271
|
-
*
|
|
272
271
|
* @param config - Client configuration
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* const client = new D402Client({
|
|
276
|
+
* operatorAccount: walletClient.account, // User's wallet from wagmi
|
|
277
|
+
* iatpWalletAddress: userWallet, // From createIATPWallet() or getWalletsByOwner()
|
|
278
|
+
* maxValue: 1000000n // Safety limit: 1 USDC max
|
|
279
|
+
* })
|
|
280
|
+
* ```
|
|
273
281
|
*/
|
|
274
282
|
constructor(config: D402ClientConfig);
|
|
275
283
|
/**
|
|
276
284
|
* Select payment requirement from list of options.
|
|
277
285
|
*
|
|
278
|
-
*
|
|
286
|
+
* Applies configured filters (network, scheme, maxValue) to choose
|
|
287
|
+
* the appropriate payment option from the server's requirements list.
|
|
279
288
|
*
|
|
280
289
|
* @param requirements - List of payment requirements from 402 response
|
|
281
290
|
* @returns Selected payment requirement
|
|
@@ -284,13 +293,13 @@ declare class D402Client {
|
|
|
284
293
|
/**
|
|
285
294
|
* Get the IATP wallet address used for payments.
|
|
286
295
|
*
|
|
287
|
-
* @returns IATPWallet contract address or
|
|
296
|
+
* @returns IATPWallet contract address, or user's EOA address if no wallet configured
|
|
288
297
|
*/
|
|
289
298
|
getIATPWalletAddress(): `0x${string}`;
|
|
290
299
|
/**
|
|
291
|
-
* Get the
|
|
300
|
+
* Get the user's account used for signing payments.
|
|
292
301
|
*
|
|
293
|
-
* @returns
|
|
302
|
+
* @returns User's wallet account
|
|
294
303
|
*/
|
|
295
304
|
getOperatorAccount(): Account;
|
|
296
305
|
/**
|
|
@@ -302,7 +311,6 @@ declare class D402Client {
|
|
|
302
311
|
/**
|
|
303
312
|
* Fetch with automatic 402 payment handling.
|
|
304
313
|
*
|
|
305
|
-
* Matches Python: HttpxHooks.on_response() (httpx.py lines 33-117)
|
|
306
314
|
*
|
|
307
315
|
* Flow:
|
|
308
316
|
* 1. Make request without payment
|
|
@@ -334,34 +342,37 @@ declare class D402Client {
|
|
|
334
342
|
|
|
335
343
|
/**
|
|
336
344
|
* EIP-712 payment signing utilities
|
|
337
|
-
*
|
|
338
|
-
* Matches Python implementation: IATP/src/traia_iatp/d402/payment_signing.py
|
|
339
345
|
*/
|
|
340
346
|
|
|
341
347
|
/**
|
|
342
348
|
* Sign a D402 payment using EIP-712 signature.
|
|
343
349
|
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
350
|
+
* Signs a payment authorization with the user's wallet (MetaMask/WalletConnect).
|
|
351
|
+
* This creates a PullFundsForSettlement signature that authorizes the payment.
|
|
346
352
|
*
|
|
347
|
-
*
|
|
353
|
+
* The user will see a MetaMask popup to approve the signature.
|
|
348
354
|
*
|
|
349
355
|
* @param params - Signing parameters
|
|
350
|
-
* @param params.operatorAccount -
|
|
356
|
+
* @param params.operatorAccount - User's account for signing (from wagmi walletClient)
|
|
351
357
|
* @param params.paymentRequirement - Payment requirements from 402 response
|
|
352
|
-
* @param params.iatpWalletAddress - IATPWallet contract address (optional
|
|
358
|
+
* @param params.iatpWalletAddress - IATPWallet contract address (optional)
|
|
353
359
|
* @param params.requestPath - API request path (optional, uses payment_requirements.resource if not provided)
|
|
354
360
|
* @returns Signed payment ready to encode and send
|
|
355
361
|
*
|
|
356
362
|
* @example
|
|
357
363
|
* ```ts
|
|
364
|
+
* // Get payment requirement from 402 response
|
|
358
365
|
* const requirement = await parsePaymentRequirement(response)
|
|
366
|
+
*
|
|
367
|
+
* // User signs payment (MetaMask popup appears)
|
|
359
368
|
* const signedPayment = await signD402Payment({
|
|
360
|
-
* operatorAccount: account,
|
|
369
|
+
* operatorAccount: walletClient.account, // User's wallet
|
|
361
370
|
* paymentRequirement: requirement,
|
|
362
|
-
* iatpWalletAddress: '
|
|
371
|
+
* iatpWalletAddress: '0xUserIATPWallet...'
|
|
363
372
|
* })
|
|
364
|
-
*
|
|
373
|
+
*
|
|
374
|
+
* // Encode for X-Payment header
|
|
375
|
+
* const paymentHeader = encodePayment(signedPayment)
|
|
365
376
|
* ```
|
|
366
377
|
*/
|
|
367
378
|
declare function signD402Payment(params: {
|
|
@@ -374,30 +385,27 @@ declare function signD402Payment(params: {
|
|
|
374
385
|
|
|
375
386
|
/**
|
|
376
387
|
* 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
388
|
*/
|
|
381
389
|
|
|
382
390
|
/**
|
|
383
391
|
* Parse payment requirements from HTTP 402 response.
|
|
384
392
|
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
* payment_response = d402PaymentRequiredResponse(**data)
|
|
388
|
-
*
|
|
389
|
-
* The 402 response body contains payment requirements in camelCase JSON format.
|
|
393
|
+
* When an API returns 402 "Payment Required", this function extracts
|
|
394
|
+
* the payment details (amount, token, network) from the response body.
|
|
390
395
|
*
|
|
391
396
|
* @param response - HTTP Response object with status 402
|
|
392
|
-
* @returns First payment requirement from
|
|
397
|
+
* @returns First payment requirement from the response
|
|
393
398
|
* @throws {Invalid402ResponseError} If response is not valid 402 or malformed
|
|
394
399
|
*
|
|
395
400
|
* @example
|
|
396
401
|
* ```ts
|
|
397
|
-
* const response = await fetch('
|
|
402
|
+
* const response = await fetch('https://sentiment-api.com/analyze')
|
|
403
|
+
*
|
|
398
404
|
* if (response.status === 402) {
|
|
399
405
|
* const requirement = await parsePaymentRequirement(response)
|
|
400
|
-
* console.log(requirement.maxAmountRequired)
|
|
406
|
+
* console.log('Payment required:', requirement.maxAmountRequired, 'wei')
|
|
407
|
+
* console.log('Token:', requirement.asset)
|
|
408
|
+
* console.log('Network:', requirement.network)
|
|
401
409
|
* }
|
|
402
410
|
* ```
|
|
403
411
|
*/
|
|
@@ -405,32 +413,32 @@ declare function parsePaymentRequirement(response: Response): Promise<PaymentReq
|
|
|
405
413
|
|
|
406
414
|
/**
|
|
407
415
|
* Base64 encoding/decoding for payment payloads
|
|
408
|
-
*
|
|
409
|
-
* Matches Python implementation: IATP/src/traia_iatp/d402/encoding.py
|
|
410
416
|
*/
|
|
411
417
|
|
|
412
418
|
/**
|
|
413
|
-
* Encode a payment
|
|
419
|
+
* Encode a signed payment to base64 string for X-Payment header.
|
|
414
420
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
421
|
+
* Takes a signed payment object and encodes it to base64 format
|
|
422
|
+
* that can be sent in the X-Payment HTTP header.
|
|
417
423
|
*
|
|
418
|
-
* @param payment -
|
|
419
|
-
* @returns Base64 encoded
|
|
424
|
+
* @param payment - Signed payment object (from signD402Payment)
|
|
425
|
+
* @returns Base64 encoded string ready for X-Payment header
|
|
420
426
|
*
|
|
421
427
|
* @example
|
|
422
428
|
* ```ts
|
|
423
|
-
* const
|
|
424
|
-
* const encoded = encodePayment(
|
|
425
|
-
*
|
|
429
|
+
* const signedPayment = await signD402Payment({...})
|
|
430
|
+
* const encoded = encodePayment(signedPayment)
|
|
431
|
+
*
|
|
432
|
+
* // Send in HTTP request
|
|
433
|
+
* fetch(url, {
|
|
434
|
+
* headers: { 'X-Payment': encoded }
|
|
435
|
+
* })
|
|
426
436
|
* ```
|
|
427
437
|
*/
|
|
428
438
|
declare function encodePayment(payment: SignedPayment): string;
|
|
429
439
|
/**
|
|
430
440
|
* Decode a base64 encoded payment string back to payment object.
|
|
431
441
|
*
|
|
432
|
-
* Matches Python: decode_payment(encoded_payment: str) -> Dict[str, Any]
|
|
433
|
-
*
|
|
434
442
|
* @param encodedPayment - Base64 encoded payment string
|
|
435
443
|
* @returns Decoded payment object
|
|
436
444
|
*
|
|
@@ -481,9 +489,12 @@ declare function getUsdcAddress(network: SupportedNetwork): `0x${string}`;
|
|
|
481
489
|
/**
|
|
482
490
|
* Get chain ID for a given network.
|
|
483
491
|
*
|
|
484
|
-
*
|
|
492
|
+
* This function maps network names to chain IDs for parsing 402 payment requirements
|
|
493
|
+
* from external APIs. It supports many networks that may appear in 402 responses,
|
|
494
|
+
* even if IATP contracts are not deployed on those networks.
|
|
485
495
|
*
|
|
486
|
-
*
|
|
496
|
+
* Note: IATP contracts are currently only deployed on Sepolia. This function exists
|
|
497
|
+
* to handle 402 responses from any API that might support other networks.
|
|
487
498
|
*
|
|
488
499
|
* @param network - Network name or chain ID as string
|
|
489
500
|
* @returns Chain ID as number
|
|
@@ -494,7 +505,7 @@ declare function getUsdcAddress(network: SupportedNetwork): `0x${string}`;
|
|
|
494
505
|
* ```ts
|
|
495
506
|
* getChainId('sepolia') // Returns 11155111
|
|
496
507
|
* getChainId('11155111') // Returns 11155111 (passthrough)
|
|
497
|
-
* getChainId('base') // Returns 8453
|
|
508
|
+
* getChainId('base') // Returns 8453 (for parsing 402 responses)
|
|
498
509
|
* ```
|
|
499
510
|
*/
|
|
500
511
|
declare function getChainId(network: string): number;
|
|
@@ -675,16 +686,13 @@ declare const EIP712_TYPES: {
|
|
|
675
686
|
};
|
|
676
687
|
|
|
677
688
|
/**
|
|
678
|
-
* Contract configuration and utilities
|
|
679
|
-
*
|
|
680
|
-
* Matches Python implementation: IATP/src/traia_iatp/contracts/config.py
|
|
689
|
+
* Contract configuration and utilities.
|
|
681
690
|
*
|
|
682
|
-
*
|
|
691
|
+
* Provides access to IATPWallet contract ABIs and deployed addresses.
|
|
692
|
+
* Contract data is bundled directly in the package for reliability.
|
|
683
693
|
*/
|
|
684
694
|
/**
|
|
685
695
|
* Supported contract names.
|
|
686
|
-
*
|
|
687
|
-
* Matches Python: ContractName enum (config.py lines 16-21)
|
|
688
696
|
*/
|
|
689
697
|
declare enum ContractName {
|
|
690
698
|
IATP_WALLET = "IATPWallet",
|
|
@@ -694,16 +702,11 @@ declare enum ContractName {
|
|
|
694
702
|
}
|
|
695
703
|
/**
|
|
696
704
|
* Supported networks for contract deployments.
|
|
697
|
-
*
|
|
698
|
-
* Matches Python: SUPPORTED_NETWORKS (config.py line 25)
|
|
699
705
|
*/
|
|
700
|
-
type SupportedContractNetwork = 'sepolia'
|
|
706
|
+
type SupportedContractNetwork = 'sepolia';
|
|
701
707
|
/**
|
|
702
708
|
* Get contract address for a given network.
|
|
703
709
|
*
|
|
704
|
-
* Matches Python: get_contract_address(contract_name: str, network: str) -> Optional[str]
|
|
705
|
-
* (config.py lines 77-118)
|
|
706
|
-
*
|
|
707
710
|
* @param contractName - Name of the contract (use ContractName enum)
|
|
708
711
|
* @param network - Network name (default: "sepolia")
|
|
709
712
|
* @param useProxy - Use proxy address if true, implementation if false (default: true)
|
|
@@ -719,9 +722,6 @@ declare function getContractAddress(contractName: string | ContractName, network
|
|
|
719
722
|
/**
|
|
720
723
|
* Get contract ABI for a given network.
|
|
721
724
|
*
|
|
722
|
-
* Matches Python: get_contract_abi(contract_name: str, network: str) -> Optional[List[dict]]
|
|
723
|
-
* (config.py lines 121-156)
|
|
724
|
-
*
|
|
725
725
|
* @param contractName - Name of the contract (use ContractName enum)
|
|
726
726
|
* @param network - Network name (default: "sepolia")
|
|
727
727
|
* @returns Contract ABI as array of objects, or null if not found
|
|
@@ -736,8 +736,6 @@ declare function getContractAbi(contractName: string | ContractName, network?: S
|
|
|
736
736
|
/**
|
|
737
737
|
* Get contract configuration (address and ABI) for a network.
|
|
738
738
|
*
|
|
739
|
-
* Matches Python: get_contract_config(network: str) from wallet_creator.py
|
|
740
|
-
*
|
|
741
739
|
* @param contractName - Name of the contract
|
|
742
740
|
* @param network - Network name (default: "sepolia")
|
|
743
741
|
* @returns Object with address and abi, or null if not found
|
|
@@ -787,23 +785,16 @@ declare function isContractDeployed(contractName: string | ContractName, network
|
|
|
787
785
|
/**
|
|
788
786
|
* IATPWallet creation and management
|
|
789
787
|
*
|
|
790
|
-
* Matches Python implementation: IATP/src/traia_iatp/scripts/create_wallet.py
|
|
791
788
|
*/
|
|
792
789
|
|
|
793
790
|
/**
|
|
794
791
|
* Result of wallet creation.
|
|
795
|
-
*
|
|
796
|
-
* Matches Python: create_wallet() return type (lines 138-147)
|
|
797
792
|
*/
|
|
798
793
|
interface WalletCreationResult {
|
|
799
794
|
/** Address of the created IATPWallet contract */
|
|
800
795
|
walletAddress: `0x${string}`;
|
|
801
|
-
/** Owner address (who created it) */
|
|
796
|
+
/** Owner address (who created it, also the operator) */
|
|
802
797
|
ownerAddress: `0x${string}`;
|
|
803
|
-
/** Operator address (can sign payments) */
|
|
804
|
-
operatorAddress: `0x${string}`;
|
|
805
|
-
/** Operator private key (store securely!) */
|
|
806
|
-
operatorPrivateKey: `0x${string}`;
|
|
807
798
|
/** Transaction hash */
|
|
808
799
|
transactionHash: Hash;
|
|
809
800
|
/** Block number where wallet was created */
|
|
@@ -816,15 +807,15 @@ interface WalletCreationResult {
|
|
|
816
807
|
/**
|
|
817
808
|
* Create a new IATPWallet using IATPWalletFactory.
|
|
818
809
|
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
810
|
+
* Creates an on-chain smart contract wallet where the user is both owner and operator.
|
|
811
|
+
* The user signs all payments themselves with their wallet (MetaMask/WalletConnect).
|
|
821
812
|
*
|
|
822
813
|
* This function:
|
|
823
|
-
* 1.
|
|
824
|
-
* 2.
|
|
814
|
+
* 1. Calls IATPWalletFactory.createWallet(ownerAddress)
|
|
815
|
+
* 2. Sets owner as operator (user signs all payments)
|
|
825
816
|
* 3. Waits for transaction confirmation
|
|
826
817
|
* 4. Extracts wallet address from WalletCreated event
|
|
827
|
-
* 5. Returns wallet
|
|
818
|
+
* 5. Returns wallet address and transaction info
|
|
828
819
|
*
|
|
829
820
|
* @param params - Creation parameters
|
|
830
821
|
* @param params.ownerAccount - Owner's account (will own the wallet)
|
|
@@ -851,9 +842,8 @@ interface WalletCreationResult {
|
|
|
851
842
|
*/
|
|
852
843
|
declare function createIATPWallet(params: {
|
|
853
844
|
ownerAccount: Account;
|
|
854
|
-
network?: 'sepolia'
|
|
845
|
+
network?: 'sepolia';
|
|
855
846
|
rpcUrl?: string;
|
|
856
|
-
operatorPrivateKey?: `0x${string}`;
|
|
857
847
|
}): Promise<WalletCreationResult>;
|
|
858
848
|
/**
|
|
859
849
|
* Get all IATPWallet addresses owned by a user.
|
|
@@ -861,29 +851,37 @@ declare function createIATPWallet(params: {
|
|
|
861
851
|
* Queries the IATPWalletFactory contract to retrieve all wallets
|
|
862
852
|
* where the specified address is the owner.
|
|
863
853
|
*
|
|
854
|
+
* Use this to check if a user already has a wallet before calling createIATPWallet().
|
|
855
|
+
*
|
|
864
856
|
* @param params - Query parameters
|
|
865
|
-
* @param params.ownerAddress -
|
|
857
|
+
* @param params.ownerAddress - User's wallet address (from MetaMask)
|
|
866
858
|
* @param params.network - Network to query (default: "sepolia")
|
|
867
859
|
* @param params.rpcUrl - Custom RPC URL (optional)
|
|
868
|
-
* @returns Array of IATPWallet contract addresses
|
|
860
|
+
* @returns Array of IATPWallet contract addresses (empty if user has no wallets)
|
|
869
861
|
*
|
|
870
862
|
* @example
|
|
871
863
|
* ```ts
|
|
872
864
|
* import { getWalletsByOwner } from '@dcentralab/d402-client'
|
|
865
|
+
* import { useAccount } from 'wagmi'
|
|
866
|
+
*
|
|
867
|
+
* const { address } = useAccount()
|
|
873
868
|
*
|
|
874
|
-
* //
|
|
869
|
+
* // Check if user has any wallets
|
|
875
870
|
* const wallets = await getWalletsByOwner({
|
|
876
|
-
* ownerAddress:
|
|
871
|
+
* ownerAddress: address,
|
|
877
872
|
* network: 'sepolia'
|
|
878
873
|
* })
|
|
879
874
|
*
|
|
880
|
-
*
|
|
881
|
-
*
|
|
875
|
+
* if (wallets.length === 0) {
|
|
876
|
+
* // Show "Create Wallet" button
|
|
877
|
+
* } else {
|
|
878
|
+
* // Use existing wallet: wallets[0]
|
|
879
|
+
* }
|
|
882
880
|
* ```
|
|
883
881
|
*/
|
|
884
882
|
declare function getWalletsByOwner(params: {
|
|
885
883
|
ownerAddress: Address;
|
|
886
|
-
network?: 'sepolia'
|
|
884
|
+
network?: 'sepolia';
|
|
887
885
|
rpcUrl?: string;
|
|
888
886
|
}): Promise<Address[]>;
|
|
889
887
|
|