@dcentralab/d402-client 0.2.2 → 0.2.4
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/index.d.mts +152 -5
- package/dist/index.d.ts +152 -5
- package/dist/index.js +510 -135
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +509 -137
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { http, createPublicClient, createWalletClient, decodeEventLog, isAddress } from 'viem';
|
|
1
|
+
import { http, createPublicClient, createWalletClient, decodeEventLog, isAddress, encodeFunctionData } from 'viem';
|
|
2
2
|
import { sepolia } from 'viem/chains';
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -509,139 +509,6 @@ function sortPaymentRequirements(requirements, preferredNetwork) {
|
|
|
509
509
|
});
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
-
// src/client.ts
|
|
513
|
-
var D402Client = class {
|
|
514
|
-
/**
|
|
515
|
-
* Create a new D402 Client.
|
|
516
|
-
*
|
|
517
|
-
* @param config - Client configuration
|
|
518
|
-
*
|
|
519
|
-
* @example
|
|
520
|
-
* ```ts
|
|
521
|
-
* const client = new D402Client({
|
|
522
|
-
* operatorAccount: walletClient.account, // User's wallet from wagmi
|
|
523
|
-
* iatpWalletAddress: userWallet, // From createIATPWallet() or getWalletsByOwner()
|
|
524
|
-
* maxValue: 1000000n // Safety limit: 1 USDC max
|
|
525
|
-
* })
|
|
526
|
-
* ```
|
|
527
|
-
*/
|
|
528
|
-
constructor(config) {
|
|
529
|
-
this.operatorAccount = config.operatorAccount;
|
|
530
|
-
this.iatpWalletAddress = config.iatpWalletAddress || config.operatorAccount.address;
|
|
531
|
-
this.maxValue = config.maxValue;
|
|
532
|
-
this.networkFilter = config.networkFilter;
|
|
533
|
-
this.schemeFilter = config.schemeFilter || "exact";
|
|
534
|
-
this.paymentRequirementsSelector = config.paymentRequirementsSelector || selectPaymentRequirement;
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* Select payment requirement from list of options.
|
|
538
|
-
*
|
|
539
|
-
* Applies configured filters (network, scheme, maxValue) to choose
|
|
540
|
-
* the appropriate payment option from the server's requirements list.
|
|
541
|
-
*
|
|
542
|
-
* @param requirements - List of payment requirements from 402 response
|
|
543
|
-
* @returns Selected payment requirement
|
|
544
|
-
*/
|
|
545
|
-
selectPaymentRequirement(requirements) {
|
|
546
|
-
return this.paymentRequirementsSelector(requirements, {
|
|
547
|
-
network: this.networkFilter,
|
|
548
|
-
scheme: this.schemeFilter,
|
|
549
|
-
maxAmount: this.maxValue
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Get the IATP wallet address used for payments.
|
|
554
|
-
*
|
|
555
|
-
* @returns IATPWallet contract address, or user's EOA address if no wallet configured
|
|
556
|
-
*/
|
|
557
|
-
getIATPWalletAddress() {
|
|
558
|
-
return this.iatpWalletAddress;
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Get the user's account used for signing payments.
|
|
562
|
-
*
|
|
563
|
-
* @returns User's wallet account
|
|
564
|
-
*/
|
|
565
|
-
getOperatorAccount() {
|
|
566
|
-
return this.operatorAccount;
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* Get the maximum payment value limit.
|
|
570
|
-
*
|
|
571
|
-
* @returns Maximum value in base units, or undefined if no limit
|
|
572
|
-
*/
|
|
573
|
-
getMaxValue() {
|
|
574
|
-
return this.maxValue;
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* Fetch with automatic 402 payment handling.
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
* Flow:
|
|
581
|
-
* 1. Make request without payment
|
|
582
|
-
* 2. If 402 response, parse payment requirements
|
|
583
|
-
* 3. Select appropriate payment option
|
|
584
|
-
* 4. Sign payment with EIP-712
|
|
585
|
-
* 5. Retry request with X-Payment header
|
|
586
|
-
* 6. Return final response
|
|
587
|
-
*
|
|
588
|
-
* @param url - URL to fetch
|
|
589
|
-
* @param init - Fetch options (method, headers, body, etc.)
|
|
590
|
-
* @returns Response object (after payment if 402)
|
|
591
|
-
*
|
|
592
|
-
* @example
|
|
593
|
-
* ```ts
|
|
594
|
-
* const client = new D402Client({ operatorAccount, iatpWalletAddress })
|
|
595
|
-
*
|
|
596
|
-
* const response = await client.fetch('http://api.example.com/analyze', {
|
|
597
|
-
* method: 'POST',
|
|
598
|
-
* headers: { 'Content-Type': 'application/json' },
|
|
599
|
-
* body: JSON.stringify({ text: 'Analyze this' })
|
|
600
|
-
* })
|
|
601
|
-
*
|
|
602
|
-
* const data = await response.json()
|
|
603
|
-
* ```
|
|
604
|
-
*/
|
|
605
|
-
async fetch(url, init) {
|
|
606
|
-
const { parseAllPaymentRequirements: parseAllPaymentRequirements2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
|
|
607
|
-
const { signD402Payment: signD402Payment2 } = await Promise.resolve().then(() => (init_signer(), signer_exports));
|
|
608
|
-
const { encodePayment: encodePayment2 } = await Promise.resolve().then(() => (init_encoder(), encoder_exports));
|
|
609
|
-
let response = await fetch(url, init);
|
|
610
|
-
if (response.status !== 402) {
|
|
611
|
-
return response;
|
|
612
|
-
}
|
|
613
|
-
try {
|
|
614
|
-
const requirements = await parseAllPaymentRequirements2(response);
|
|
615
|
-
const selectedRequirement = this.selectPaymentRequirement(requirements);
|
|
616
|
-
const signedPayment = await signD402Payment2({
|
|
617
|
-
operatorAccount: this.operatorAccount,
|
|
618
|
-
paymentRequirement: selectedRequirement,
|
|
619
|
-
iatpWalletAddress: this.iatpWalletAddress
|
|
620
|
-
});
|
|
621
|
-
const paymentHeader = encodePayment2(signedPayment);
|
|
622
|
-
response = await fetch(url, {
|
|
623
|
-
...init,
|
|
624
|
-
headers: {
|
|
625
|
-
...init?.headers,
|
|
626
|
-
"X-Payment": paymentHeader,
|
|
627
|
-
"Access-Control-Expose-Headers": "X-Payment-Response"
|
|
628
|
-
}
|
|
629
|
-
});
|
|
630
|
-
return response;
|
|
631
|
-
} catch (error) {
|
|
632
|
-
throw error;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
// src/index.ts
|
|
638
|
-
init_signer();
|
|
639
|
-
init_parser();
|
|
640
|
-
init_encoder();
|
|
641
|
-
init_utils();
|
|
642
|
-
init_errors();
|
|
643
|
-
init_constants();
|
|
644
|
-
|
|
645
512
|
// src/contracts/abis/sepolia.json
|
|
646
513
|
var sepolia_default = {
|
|
647
514
|
sepolia: {
|
|
@@ -1211,6 +1078,25 @@ var sepolia_default = {
|
|
|
1211
1078
|
stateMutability: "nonpayable",
|
|
1212
1079
|
type: "function"
|
|
1213
1080
|
},
|
|
1081
|
+
{
|
|
1082
|
+
inputs: [
|
|
1083
|
+
{
|
|
1084
|
+
internalType: "address",
|
|
1085
|
+
name: "token",
|
|
1086
|
+
type: "address"
|
|
1087
|
+
}
|
|
1088
|
+
],
|
|
1089
|
+
name: "getAvailableBalance",
|
|
1090
|
+
outputs: [
|
|
1091
|
+
{
|
|
1092
|
+
internalType: "uint256",
|
|
1093
|
+
name: "",
|
|
1094
|
+
type: "uint256"
|
|
1095
|
+
}
|
|
1096
|
+
],
|
|
1097
|
+
stateMutability: "view",
|
|
1098
|
+
type: "function"
|
|
1099
|
+
},
|
|
1214
1100
|
{
|
|
1215
1101
|
inputs: [
|
|
1216
1102
|
{
|
|
@@ -1323,6 +1209,50 @@ var sepolia_default = {
|
|
|
1323
1209
|
stateMutability: "view",
|
|
1324
1210
|
type: "function"
|
|
1325
1211
|
},
|
|
1212
|
+
{
|
|
1213
|
+
inputs: [
|
|
1214
|
+
{
|
|
1215
|
+
internalType: "address",
|
|
1216
|
+
name: "token",
|
|
1217
|
+
type: "address"
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
internalType: "uint256",
|
|
1221
|
+
name: "amount",
|
|
1222
|
+
type: "uint256"
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
internalType: "address",
|
|
1226
|
+
name: "provider",
|
|
1227
|
+
type: "address"
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
internalType: "uint256",
|
|
1231
|
+
name: "deadline",
|
|
1232
|
+
type: "uint256"
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
internalType: "string",
|
|
1236
|
+
name: "requestPath",
|
|
1237
|
+
type: "string"
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
internalType: "bytes",
|
|
1241
|
+
name: "signature",
|
|
1242
|
+
type: "bytes"
|
|
1243
|
+
}
|
|
1244
|
+
],
|
|
1245
|
+
name: "isValidSettlementRequest",
|
|
1246
|
+
outputs: [
|
|
1247
|
+
{
|
|
1248
|
+
internalType: "bool",
|
|
1249
|
+
name: "",
|
|
1250
|
+
type: "bool"
|
|
1251
|
+
}
|
|
1252
|
+
],
|
|
1253
|
+
stateMutability: "view",
|
|
1254
|
+
type: "function"
|
|
1255
|
+
},
|
|
1326
1256
|
{
|
|
1327
1257
|
inputs: [],
|
|
1328
1258
|
name: "operatorAddress",
|
|
@@ -1563,6 +1493,11 @@ var sepolia_default = {
|
|
|
1563
1493
|
internalType: "address",
|
|
1564
1494
|
name: "token",
|
|
1565
1495
|
type: "address"
|
|
1496
|
+
},
|
|
1497
|
+
{
|
|
1498
|
+
internalType: "bool",
|
|
1499
|
+
name: "sendToOwner",
|
|
1500
|
+
type: "bool"
|
|
1566
1501
|
}
|
|
1567
1502
|
],
|
|
1568
1503
|
name: "withdrawAllFromSettlement",
|
|
@@ -2552,6 +2487,31 @@ var sepolia_default = {
|
|
|
2552
2487
|
name: "EpochReleased",
|
|
2553
2488
|
type: "event"
|
|
2554
2489
|
},
|
|
2490
|
+
{
|
|
2491
|
+
anonymous: false,
|
|
2492
|
+
inputs: [
|
|
2493
|
+
{
|
|
2494
|
+
indexed: true,
|
|
2495
|
+
internalType: "address",
|
|
2496
|
+
name: "facilitator",
|
|
2497
|
+
type: "address"
|
|
2498
|
+
},
|
|
2499
|
+
{
|
|
2500
|
+
indexed: true,
|
|
2501
|
+
internalType: "address",
|
|
2502
|
+
name: "token",
|
|
2503
|
+
type: "address"
|
|
2504
|
+
},
|
|
2505
|
+
{
|
|
2506
|
+
indexed: false,
|
|
2507
|
+
internalType: "uint256",
|
|
2508
|
+
name: "amount",
|
|
2509
|
+
type: "uint256"
|
|
2510
|
+
}
|
|
2511
|
+
],
|
|
2512
|
+
name: "FacilitatorEarningsWithdrawn",
|
|
2513
|
+
type: "event"
|
|
2514
|
+
},
|
|
2555
2515
|
{
|
|
2556
2516
|
anonymous: false,
|
|
2557
2517
|
inputs: [
|
|
@@ -2970,6 +2930,11 @@ var sepolia_default = {
|
|
|
2970
2930
|
internalType: "struct IIATPSettlementLayer.SettlementRequest",
|
|
2971
2931
|
name: "req",
|
|
2972
2932
|
type: "tuple"
|
|
2933
|
+
},
|
|
2934
|
+
{
|
|
2935
|
+
internalType: "address",
|
|
2936
|
+
name: "facilitator",
|
|
2937
|
+
type: "address"
|
|
2973
2938
|
}
|
|
2974
2939
|
],
|
|
2975
2940
|
name: "_settleRequest",
|
|
@@ -3182,6 +3147,30 @@ var sepolia_default = {
|
|
|
3182
3147
|
stateMutability: "view",
|
|
3183
3148
|
type: "function"
|
|
3184
3149
|
},
|
|
3150
|
+
{
|
|
3151
|
+
inputs: [
|
|
3152
|
+
{
|
|
3153
|
+
internalType: "address",
|
|
3154
|
+
name: "",
|
|
3155
|
+
type: "address"
|
|
3156
|
+
},
|
|
3157
|
+
{
|
|
3158
|
+
internalType: "address",
|
|
3159
|
+
name: "",
|
|
3160
|
+
type: "address"
|
|
3161
|
+
}
|
|
3162
|
+
],
|
|
3163
|
+
name: "facilitatorFeeBalances",
|
|
3164
|
+
outputs: [
|
|
3165
|
+
{
|
|
3166
|
+
internalType: "uint256",
|
|
3167
|
+
name: "",
|
|
3168
|
+
type: "uint256"
|
|
3169
|
+
}
|
|
3170
|
+
],
|
|
3171
|
+
stateMutability: "view",
|
|
3172
|
+
type: "function"
|
|
3173
|
+
},
|
|
3185
3174
|
{
|
|
3186
3175
|
inputs: [
|
|
3187
3176
|
{
|
|
@@ -3302,6 +3291,30 @@ var sepolia_default = {
|
|
|
3302
3291
|
stateMutability: "view",
|
|
3303
3292
|
type: "function"
|
|
3304
3293
|
},
|
|
3294
|
+
{
|
|
3295
|
+
inputs: [
|
|
3296
|
+
{
|
|
3297
|
+
internalType: "address",
|
|
3298
|
+
name: "facilitator",
|
|
3299
|
+
type: "address"
|
|
3300
|
+
},
|
|
3301
|
+
{
|
|
3302
|
+
internalType: "address",
|
|
3303
|
+
name: "token",
|
|
3304
|
+
type: "address"
|
|
3305
|
+
}
|
|
3306
|
+
],
|
|
3307
|
+
name: "getFacilitatorEarnings",
|
|
3308
|
+
outputs: [
|
|
3309
|
+
{
|
|
3310
|
+
internalType: "uint256",
|
|
3311
|
+
name: "",
|
|
3312
|
+
type: "uint256"
|
|
3313
|
+
}
|
|
3314
|
+
],
|
|
3315
|
+
stateMutability: "view",
|
|
3316
|
+
type: "function"
|
|
3317
|
+
},
|
|
3305
3318
|
{
|
|
3306
3319
|
inputs: [
|
|
3307
3320
|
{
|
|
@@ -4010,6 +4023,30 @@ var sepolia_default = {
|
|
|
4010
4023
|
stateMutability: "view",
|
|
4011
4024
|
type: "function"
|
|
4012
4025
|
},
|
|
4026
|
+
{
|
|
4027
|
+
inputs: [
|
|
4028
|
+
{
|
|
4029
|
+
internalType: "uint256",
|
|
4030
|
+
name: "amount",
|
|
4031
|
+
type: "uint256"
|
|
4032
|
+
},
|
|
4033
|
+
{
|
|
4034
|
+
internalType: "uint256",
|
|
4035
|
+
name: "facilitatorFeePercent",
|
|
4036
|
+
type: "uint256"
|
|
4037
|
+
}
|
|
4038
|
+
],
|
|
4039
|
+
name: "validatePaymentAmount",
|
|
4040
|
+
outputs: [
|
|
4041
|
+
{
|
|
4042
|
+
internalType: "bool",
|
|
4043
|
+
name: "isValid",
|
|
4044
|
+
type: "bool"
|
|
4045
|
+
}
|
|
4046
|
+
],
|
|
4047
|
+
stateMutability: "view",
|
|
4048
|
+
type: "function"
|
|
4049
|
+
},
|
|
4013
4050
|
{
|
|
4014
4051
|
inputs: [
|
|
4015
4052
|
{
|
|
@@ -4040,6 +4077,19 @@ var sepolia_default = {
|
|
|
4040
4077
|
outputs: [],
|
|
4041
4078
|
stateMutability: "nonpayable",
|
|
4042
4079
|
type: "function"
|
|
4080
|
+
},
|
|
4081
|
+
{
|
|
4082
|
+
inputs: [
|
|
4083
|
+
{
|
|
4084
|
+
internalType: "address[]",
|
|
4085
|
+
name: "tokens",
|
|
4086
|
+
type: "address[]"
|
|
4087
|
+
}
|
|
4088
|
+
],
|
|
4089
|
+
name: "withdrawFacilitatorEarnings",
|
|
4090
|
+
outputs: [],
|
|
4091
|
+
stateMutability: "nonpayable",
|
|
4092
|
+
type: "function"
|
|
4043
4093
|
}
|
|
4044
4094
|
],
|
|
4045
4095
|
IATPWalletFactory: [
|
|
@@ -4749,9 +4799,9 @@ var implementations_default = {
|
|
|
4749
4799
|
sepolia: {
|
|
4750
4800
|
Congress: "0x94Fc9eddBd1779542b78eb92F0569762603876e2",
|
|
4751
4801
|
TraiaCongressMembersRegistry: "0x3B685403b195f16D103b42FCf56F848A278d6049",
|
|
4752
|
-
IATPWalletImplementation: "
|
|
4802
|
+
IATPWalletImplementation: "0xfE32B4ae6606F70342749AD0C62E1C7e5F84E1B4",
|
|
4753
4803
|
RoleManagerImplementation: "0x585AD85FCFBec3B1503E50b46407bF65d4006560",
|
|
4754
|
-
IATPSettlementLayerImplementation: "
|
|
4804
|
+
IATPSettlementLayerImplementation: "0x0fDd39d323EE3538c800d4A13730eecE3F0bA975",
|
|
4755
4805
|
IATPWalletFactoryImplementation: "0xA1E5a53cE5b4e78801d9394EC60D0B53390CA240"
|
|
4756
4806
|
}
|
|
4757
4807
|
};
|
|
@@ -4800,6 +4850,8 @@ function isContractDeployed(contractName, network) {
|
|
|
4800
4850
|
const abi = getContractAbi(contractName, network);
|
|
4801
4851
|
return address !== null && abi !== null;
|
|
4802
4852
|
}
|
|
4853
|
+
|
|
4854
|
+
// src/wallet.ts
|
|
4803
4855
|
async function createIATPWallet(params) {
|
|
4804
4856
|
const { ownerAccount, network = "sepolia", rpcUrl } = params;
|
|
4805
4857
|
const factoryConfig = getContractConfig("IATPWalletFactory" /* IATP_WALLET_FACTORY */, network);
|
|
@@ -4887,7 +4939,327 @@ async function getWalletsByOwner(params) {
|
|
|
4887
4939
|
});
|
|
4888
4940
|
return wallets;
|
|
4889
4941
|
}
|
|
4942
|
+
async function getAvailableBalance(params) {
|
|
4943
|
+
const { publicClient, walletAddress, tokenAddress, network = "sepolia" } = params;
|
|
4944
|
+
const walletConfig = getContractConfig("IATPWallet" /* IATP_WALLET */, network);
|
|
4945
|
+
if (!walletConfig) {
|
|
4946
|
+
throw new Error(`IATPWallet contract not found for network: ${network}`);
|
|
4947
|
+
}
|
|
4948
|
+
const balance = await publicClient.readContract({
|
|
4949
|
+
address: walletAddress,
|
|
4950
|
+
abi: walletConfig.abi,
|
|
4951
|
+
functionName: "getAvailableBalance",
|
|
4952
|
+
args: [tokenAddress]
|
|
4953
|
+
});
|
|
4954
|
+
return balance;
|
|
4955
|
+
}
|
|
4956
|
+
async function getWithdrawalRequest(params) {
|
|
4957
|
+
const { publicClient, walletAddress, tokenAddress, network = "sepolia" } = params;
|
|
4958
|
+
const walletConfig = getContractConfig("IATPWallet" /* IATP_WALLET */, network);
|
|
4959
|
+
if (!walletConfig) {
|
|
4960
|
+
throw new Error(`IATPWallet contract not found for network: ${network}`);
|
|
4961
|
+
}
|
|
4962
|
+
const result = await publicClient.readContract({
|
|
4963
|
+
address: walletAddress,
|
|
4964
|
+
abi: walletConfig.abi,
|
|
4965
|
+
functionName: "getWithdrawalRequest",
|
|
4966
|
+
args: [tokenAddress]
|
|
4967
|
+
});
|
|
4968
|
+
if (result[0] === 0n) {
|
|
4969
|
+
return null;
|
|
4970
|
+
}
|
|
4971
|
+
return result;
|
|
4972
|
+
}
|
|
4973
|
+
async function requestWithdrawal(params) {
|
|
4974
|
+
const { walletClient, publicClient, walletAddress, tokenAddress, amount, account, network = "sepolia" } = params;
|
|
4975
|
+
const walletConfig = getContractConfig("IATPWallet" /* IATP_WALLET */, network);
|
|
4976
|
+
if (!walletConfig) {
|
|
4977
|
+
throw new Error(`IATPWallet contract not found for network: ${network}`);
|
|
4978
|
+
}
|
|
4979
|
+
const data = encodeFunctionData({
|
|
4980
|
+
abi: walletConfig.abi,
|
|
4981
|
+
functionName: "requestWithdrawal",
|
|
4982
|
+
args: [tokenAddress, amount]
|
|
4983
|
+
});
|
|
4984
|
+
const estimatedGas = await publicClient.estimateGas({
|
|
4985
|
+
account: account.address,
|
|
4986
|
+
to: walletAddress,
|
|
4987
|
+
data
|
|
4988
|
+
});
|
|
4989
|
+
const gasLimit = estimatedGas + estimatedGas * BigInt(20) / BigInt(100);
|
|
4990
|
+
const { request } = await publicClient.simulateContract({
|
|
4991
|
+
account,
|
|
4992
|
+
address: walletAddress,
|
|
4993
|
+
abi: walletConfig.abi,
|
|
4994
|
+
functionName: "requestWithdrawal",
|
|
4995
|
+
args: [tokenAddress, amount]
|
|
4996
|
+
});
|
|
4997
|
+
const hash = await walletClient.writeContract({
|
|
4998
|
+
...request,
|
|
4999
|
+
gas: gasLimit
|
|
5000
|
+
});
|
|
5001
|
+
await publicClient.waitForTransactionReceipt({ hash });
|
|
5002
|
+
return hash;
|
|
5003
|
+
}
|
|
5004
|
+
async function executeWithdrawal(params) {
|
|
5005
|
+
const { walletClient, publicClient, walletAddress, tokenAddress, account, network = "sepolia" } = params;
|
|
5006
|
+
const walletConfig = getContractConfig("IATPWallet" /* IATP_WALLET */, network);
|
|
5007
|
+
if (!walletConfig) {
|
|
5008
|
+
throw new Error(`IATPWallet contract not found for network: ${network}`);
|
|
5009
|
+
}
|
|
5010
|
+
const data = encodeFunctionData({
|
|
5011
|
+
abi: walletConfig.abi,
|
|
5012
|
+
functionName: "executeWithdrawal",
|
|
5013
|
+
args: [tokenAddress]
|
|
5014
|
+
});
|
|
5015
|
+
const estimatedGas = await publicClient.estimateGas({
|
|
5016
|
+
account: account.address,
|
|
5017
|
+
to: walletAddress,
|
|
5018
|
+
data
|
|
5019
|
+
});
|
|
5020
|
+
const gasLimit = estimatedGas + estimatedGas * BigInt(20) / BigInt(100);
|
|
5021
|
+
const { request } = await publicClient.simulateContract({
|
|
5022
|
+
account,
|
|
5023
|
+
address: walletAddress,
|
|
5024
|
+
abi: walletConfig.abi,
|
|
5025
|
+
functionName: "executeWithdrawal",
|
|
5026
|
+
args: [tokenAddress]
|
|
5027
|
+
});
|
|
5028
|
+
const hash = await walletClient.writeContract({
|
|
5029
|
+
...request,
|
|
5030
|
+
gas: gasLimit
|
|
5031
|
+
});
|
|
5032
|
+
await publicClient.waitForTransactionReceipt({ hash });
|
|
5033
|
+
return hash;
|
|
5034
|
+
}
|
|
5035
|
+
|
|
5036
|
+
// src/client.ts
|
|
5037
|
+
var D402Client = class {
|
|
5038
|
+
/**
|
|
5039
|
+
* Create a new D402 Client.
|
|
5040
|
+
*
|
|
5041
|
+
* @param config - Client configuration
|
|
5042
|
+
*
|
|
5043
|
+
* @example
|
|
5044
|
+
* ```ts
|
|
5045
|
+
* const client = new D402Client({
|
|
5046
|
+
* operatorAccount: walletClient.account, // User's wallet from wagmi
|
|
5047
|
+
* iatpWalletAddress: userWallet, // From createIATPWallet() or getWalletsByOwner()
|
|
5048
|
+
* maxValue: 1000000n // Safety limit: 1 USDC max
|
|
5049
|
+
* })
|
|
5050
|
+
* ```
|
|
5051
|
+
*/
|
|
5052
|
+
constructor(config) {
|
|
5053
|
+
this.operatorAccount = config.operatorAccount;
|
|
5054
|
+
this.iatpWalletAddress = config.iatpWalletAddress;
|
|
5055
|
+
this.maxValue = config.maxValue;
|
|
5056
|
+
this.networkFilter = config.networkFilter;
|
|
5057
|
+
this.schemeFilter = config.schemeFilter || "exact";
|
|
5058
|
+
this.paymentRequirementsSelector = config.paymentRequirementsSelector || selectPaymentRequirement;
|
|
5059
|
+
}
|
|
5060
|
+
/**
|
|
5061
|
+
* Select payment requirement from list of options.
|
|
5062
|
+
*
|
|
5063
|
+
* Applies configured filters (network, scheme, maxValue) to choose
|
|
5064
|
+
* the appropriate payment option from the server's requirements list.
|
|
5065
|
+
*
|
|
5066
|
+
* @param requirements - List of payment requirements from 402 response
|
|
5067
|
+
* @returns Selected payment requirement
|
|
5068
|
+
*/
|
|
5069
|
+
selectPaymentRequirement(requirements) {
|
|
5070
|
+
return this.paymentRequirementsSelector(requirements, {
|
|
5071
|
+
network: this.networkFilter,
|
|
5072
|
+
scheme: this.schemeFilter,
|
|
5073
|
+
maxAmount: this.maxValue
|
|
5074
|
+
});
|
|
5075
|
+
}
|
|
5076
|
+
/**
|
|
5077
|
+
* Get the IATP wallet address used for payments.
|
|
5078
|
+
*
|
|
5079
|
+
* @returns IATPWallet contract address, or user's EOA address if no wallet configured
|
|
5080
|
+
*/
|
|
5081
|
+
getIATPWalletAddress() {
|
|
5082
|
+
return this.iatpWalletAddress;
|
|
5083
|
+
}
|
|
5084
|
+
/**
|
|
5085
|
+
* Get the user's account used for signing payments.
|
|
5086
|
+
*
|
|
5087
|
+
* @returns User's wallet account
|
|
5088
|
+
*/
|
|
5089
|
+
getOperatorAccount() {
|
|
5090
|
+
return this.operatorAccount;
|
|
5091
|
+
}
|
|
5092
|
+
/**
|
|
5093
|
+
* Get the maximum payment value limit.
|
|
5094
|
+
*
|
|
5095
|
+
* @returns Maximum value in base units, or undefined if no limit
|
|
5096
|
+
*/
|
|
5097
|
+
getMaxValue() {
|
|
5098
|
+
return this.maxValue;
|
|
5099
|
+
}
|
|
5100
|
+
/**
|
|
5101
|
+
* Get available balance for a token in the IATP wallet.
|
|
5102
|
+
*
|
|
5103
|
+
* @param publicClient - Viem PublicClient (from wagmi usePublicClient)
|
|
5104
|
+
* @param tokenAddress - Token contract address
|
|
5105
|
+
* @returns Available balance in token's base units (wei)
|
|
5106
|
+
*/
|
|
5107
|
+
async getAvailableBalance(publicClient, tokenAddress) {
|
|
5108
|
+
return getAvailableBalance({
|
|
5109
|
+
publicClient,
|
|
5110
|
+
walletAddress: this.iatpWalletAddress,
|
|
5111
|
+
tokenAddress
|
|
5112
|
+
});
|
|
5113
|
+
}
|
|
5114
|
+
/**
|
|
5115
|
+
* Get withdrawal request for a token.
|
|
5116
|
+
*
|
|
5117
|
+
* @param publicClient - Viem PublicClient
|
|
5118
|
+
* @param tokenAddress - Token contract address
|
|
5119
|
+
* @returns Withdrawal request: [amount, unlockTimestamp] or null if no request exists
|
|
5120
|
+
*/
|
|
5121
|
+
async getWithdrawalRequest(publicClient, tokenAddress) {
|
|
5122
|
+
return getWithdrawalRequest({
|
|
5123
|
+
publicClient,
|
|
5124
|
+
walletAddress: this.iatpWalletAddress,
|
|
5125
|
+
tokenAddress
|
|
5126
|
+
});
|
|
5127
|
+
}
|
|
5128
|
+
/**
|
|
5129
|
+
* Request a withdrawal from the IATP wallet.
|
|
5130
|
+
*
|
|
5131
|
+
* @param walletClient - Viem WalletClient (from wagmi useWalletClient)
|
|
5132
|
+
* @param publicClient - Viem PublicClient (from wagmi usePublicClient)
|
|
5133
|
+
* @param tokenAddress - Token contract address
|
|
5134
|
+
* @param amount - Amount in token's base units (wei)
|
|
5135
|
+
* @returns Transaction hash
|
|
5136
|
+
*/
|
|
5137
|
+
async requestWithdrawal(walletClient, publicClient, tokenAddress, amount) {
|
|
5138
|
+
return requestWithdrawal({
|
|
5139
|
+
walletClient,
|
|
5140
|
+
publicClient,
|
|
5141
|
+
walletAddress: this.iatpWalletAddress,
|
|
5142
|
+
tokenAddress,
|
|
5143
|
+
amount,
|
|
5144
|
+
account: this.operatorAccount
|
|
5145
|
+
});
|
|
5146
|
+
}
|
|
5147
|
+
/**
|
|
5148
|
+
* Execute a withdrawal for a token (after unlock period).
|
|
5149
|
+
*
|
|
5150
|
+
* @param walletClient - Viem WalletClient
|
|
5151
|
+
* @param publicClient - Viem PublicClient
|
|
5152
|
+
* @param tokenAddress - Token contract address
|
|
5153
|
+
* @returns Transaction hash
|
|
5154
|
+
*/
|
|
5155
|
+
async executeWithdrawal(walletClient, publicClient, tokenAddress) {
|
|
5156
|
+
return executeWithdrawal({
|
|
5157
|
+
walletClient,
|
|
5158
|
+
publicClient,
|
|
5159
|
+
walletAddress: this.iatpWalletAddress,
|
|
5160
|
+
tokenAddress,
|
|
5161
|
+
account: this.operatorAccount
|
|
5162
|
+
});
|
|
5163
|
+
}
|
|
5164
|
+
/**
|
|
5165
|
+
* Fetch with automatic 402 payment handling.
|
|
5166
|
+
*
|
|
5167
|
+
*
|
|
5168
|
+
* Flow:
|
|
5169
|
+
* 1. Make request without payment
|
|
5170
|
+
* 2. If 402 response, parse payment requirements
|
|
5171
|
+
* 3. Select appropriate payment option
|
|
5172
|
+
* 4. Sign payment with EIP-712
|
|
5173
|
+
* 5. Retry request with X-Payment header
|
|
5174
|
+
* 6. Return final response
|
|
5175
|
+
*
|
|
5176
|
+
* @param url - URL to fetch
|
|
5177
|
+
* @param init - Fetch options (method, headers, body, etc.)
|
|
5178
|
+
* @returns Response object (after payment if 402)
|
|
5179
|
+
*
|
|
5180
|
+
* @example
|
|
5181
|
+
* ```ts
|
|
5182
|
+
* const client = new D402Client({ operatorAccount, iatpWalletAddress })
|
|
5183
|
+
*
|
|
5184
|
+
* const response = await client.fetch('http://api.example.com/analyze', {
|
|
5185
|
+
* method: 'POST',
|
|
5186
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
5187
|
+
* body: JSON.stringify({ text: 'Analyze this' })
|
|
5188
|
+
* })
|
|
5189
|
+
*
|
|
5190
|
+
* const data = await response.json()
|
|
5191
|
+
* ```
|
|
5192
|
+
*/
|
|
5193
|
+
async fetch(url, init) {
|
|
5194
|
+
const { parseAllPaymentRequirements: parseAllPaymentRequirements2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
|
|
5195
|
+
const { signD402Payment: signD402Payment2 } = await Promise.resolve().then(() => (init_signer(), signer_exports));
|
|
5196
|
+
const { encodePayment: encodePayment2 } = await Promise.resolve().then(() => (init_encoder(), encoder_exports));
|
|
5197
|
+
let response = await fetch(url, init);
|
|
5198
|
+
if (response.status !== 402) {
|
|
5199
|
+
return response;
|
|
5200
|
+
}
|
|
5201
|
+
try {
|
|
5202
|
+
const requirements = await parseAllPaymentRequirements2(response);
|
|
5203
|
+
const selectedRequirement = this.selectPaymentRequirement(requirements);
|
|
5204
|
+
const signedPayment = await signD402Payment2({
|
|
5205
|
+
operatorAccount: this.operatorAccount,
|
|
5206
|
+
paymentRequirement: selectedRequirement,
|
|
5207
|
+
iatpWalletAddress: this.iatpWalletAddress
|
|
5208
|
+
});
|
|
5209
|
+
const paymentHeader = encodePayment2(signedPayment);
|
|
5210
|
+
response = await fetch(url, {
|
|
5211
|
+
...init,
|
|
5212
|
+
headers: {
|
|
5213
|
+
...init?.headers,
|
|
5214
|
+
"X-Payment": paymentHeader,
|
|
5215
|
+
"Access-Control-Expose-Headers": "X-Payment-Response"
|
|
5216
|
+
}
|
|
5217
|
+
});
|
|
5218
|
+
return response;
|
|
5219
|
+
} catch (error) {
|
|
5220
|
+
throw error;
|
|
5221
|
+
}
|
|
5222
|
+
}
|
|
5223
|
+
};
|
|
5224
|
+
|
|
5225
|
+
// src/index.ts
|
|
5226
|
+
init_signer();
|
|
5227
|
+
init_parser();
|
|
5228
|
+
init_encoder();
|
|
5229
|
+
init_utils();
|
|
5230
|
+
init_errors();
|
|
5231
|
+
init_constants();
|
|
5232
|
+
|
|
5233
|
+
// src/settlement.ts
|
|
5234
|
+
async function getLockedBalanceForProvider(params) {
|
|
5235
|
+
const { publicClient, settlementLayerAddress, providerAddress, tokenAddress, network = "sepolia" } = params;
|
|
5236
|
+
const settlementConfig = getContractConfig("IATPSettlementLayer" /* IATP_SETTLEMENT_LAYER */, network);
|
|
5237
|
+
if (!settlementConfig) {
|
|
5238
|
+
throw new Error(`IATPSettlementLayer contract not found for network: ${network}`);
|
|
5239
|
+
}
|
|
5240
|
+
const balance = await publicClient.readContract({
|
|
5241
|
+
address: settlementLayerAddress,
|
|
5242
|
+
abi: settlementConfig.abi,
|
|
5243
|
+
functionName: "getLockedBalanceForProvider",
|
|
5244
|
+
args: [providerAddress, tokenAddress]
|
|
5245
|
+
});
|
|
5246
|
+
return balance;
|
|
5247
|
+
}
|
|
5248
|
+
async function getUnlockedBalanceForProvider(params) {
|
|
5249
|
+
const { publicClient, settlementLayerAddress, providerAddress, tokenAddress, network = "sepolia" } = params;
|
|
5250
|
+
const settlementConfig = getContractConfig("IATPSettlementLayer" /* IATP_SETTLEMENT_LAYER */, network);
|
|
5251
|
+
if (!settlementConfig) {
|
|
5252
|
+
throw new Error(`IATPSettlementLayer contract not found for network: ${network}`);
|
|
5253
|
+
}
|
|
5254
|
+
const balance = await publicClient.readContract({
|
|
5255
|
+
address: settlementLayerAddress,
|
|
5256
|
+
abi: settlementConfig.abi,
|
|
5257
|
+
functionName: "getUnlockedBalanceForProvider",
|
|
5258
|
+
args: [providerAddress, tokenAddress]
|
|
5259
|
+
});
|
|
5260
|
+
return balance;
|
|
5261
|
+
}
|
|
4890
5262
|
|
|
4891
|
-
export { CHAIN_IDS, ContractName, D402Client, DEFAULT_VALIDITY_WINDOW_SECONDS, EIP712_TYPES, Invalid402ResponseError, MissingRequestConfigError, NETWORKS, PaymentAlreadyAttemptedError, PaymentAmountExceededError, PaymentError, PaymentVerificationError, TOKEN_ADDRESSES, UnsupportedNetworkError, UnsupportedSchemeError, createIATPWallet, createPaymentSelector, decodePayment, decodePaymentResponse, encodePayment, findMatchingPaymentRequirement, formatMoney, generateNonce, getAllContractAddresses, getChainId, getContractAbi, getContractAddress, getContractConfig, getCurrentTimestamp, getUsdcAddress, getWalletsByOwner, isContractDeployed, isValidAddress, normalizeAddress, parseMoney, parsePaymentRequirement, selectPaymentRequirement, signD402Payment, sortPaymentRequirements, usdToUsdc };
|
|
5263
|
+
export { CHAIN_IDS, ContractName, D402Client, DEFAULT_VALIDITY_WINDOW_SECONDS, EIP712_TYPES, Invalid402ResponseError, MissingRequestConfigError, NETWORKS, PaymentAlreadyAttemptedError, PaymentAmountExceededError, PaymentError, PaymentVerificationError, TOKEN_ADDRESSES, UnsupportedNetworkError, UnsupportedSchemeError, createIATPWallet, createPaymentSelector, decodePayment, decodePaymentResponse, encodePayment, findMatchingPaymentRequirement, formatMoney, generateNonce, getAllContractAddresses, getAvailableBalance, getChainId, getContractAbi, getContractAddress, getContractConfig, getCurrentTimestamp, getLockedBalanceForProvider, getUnlockedBalanceForProvider, getUsdcAddress, getWalletsByOwner, isContractDeployed, isValidAddress, normalizeAddress, parseMoney, parsePaymentRequirement, selectPaymentRequirement, signD402Payment, sortPaymentRequirements, usdToUsdc };
|
|
4892
5264
|
//# sourceMappingURL=index.mjs.map
|
|
4893
5265
|
//# sourceMappingURL=index.mjs.map
|