@bbuilders/djeon402-sdk-client 1.0.1

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,1230 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Djeon402Provider: () => Djeon402Provider,
24
+ useApprove: () => useApprove,
25
+ useBalance: () => useBalance,
26
+ useDjeon402: () => useDjeon402,
27
+ useIsBlacklisted: () => useIsBlacklisted,
28
+ useKYCData: () => useKYCData,
29
+ useTokenInfo: () => useTokenInfo,
30
+ useTransfer: () => useTransfer,
31
+ useX402Receive: () => useX402Receive,
32
+ useX402Transfer: () => useX402Transfer
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/react/provider.tsx
37
+ var import_react = require("react");
38
+
39
+ // src/client.ts
40
+ var import_viem = require("viem");
41
+ var import_chains = require("viem/chains");
42
+
43
+ // src/modules/admin.ts
44
+ var import_djeon402_core = require("@bbuilders/djeon402-core");
45
+ var AdminModule = class {
46
+ constructor(sdk) {
47
+ this.sdk = sdk;
48
+ }
49
+ /**
50
+ * Get role hashes
51
+ */
52
+ async getRoles() {
53
+ const [minter, burner, pauser, blacklister, admin] = await Promise.all([
54
+ this.sdk.publicClient.readContract({
55
+ address: this.sdk.contractAddress,
56
+ abi: import_djeon402_core.DJEON402_ABI,
57
+ functionName: "MINTER_ROLE"
58
+ }),
59
+ this.sdk.publicClient.readContract({
60
+ address: this.sdk.contractAddress,
61
+ abi: import_djeon402_core.DJEON402_ABI,
62
+ functionName: "BURNER_ROLE"
63
+ }),
64
+ this.sdk.publicClient.readContract({
65
+ address: this.sdk.contractAddress,
66
+ abi: import_djeon402_core.DJEON402_ABI,
67
+ functionName: "PAUSER_ROLE"
68
+ }),
69
+ this.sdk.publicClient.readContract({
70
+ address: this.sdk.contractAddress,
71
+ abi: import_djeon402_core.DJEON402_ABI,
72
+ functionName: "BLACKLISTER_ROLE"
73
+ }),
74
+ this.sdk.publicClient.readContract({
75
+ address: this.sdk.contractAddress,
76
+ abi: import_djeon402_core.DJEON402_ABI,
77
+ functionName: "DEFAULT_ADMIN_ROLE"
78
+ })
79
+ ]);
80
+ return {
81
+ MINTER_ROLE: minter,
82
+ BURNER_ROLE: burner,
83
+ PAUSER_ROLE: pauser,
84
+ BLACKLISTER_ROLE: blacklister,
85
+ DEFAULT_ADMIN_ROLE: admin
86
+ };
87
+ }
88
+ /**
89
+ * Check if address has role
90
+ */
91
+ async hasRole(role, account) {
92
+ (0, import_djeon402_core.validateAddress)(account);
93
+ const result = await this.sdk.publicClient.readContract({
94
+ address: this.sdk.contractAddress,
95
+ abi: import_djeon402_core.DJEON402_ABI,
96
+ functionName: "hasRole",
97
+ args: [role, account]
98
+ });
99
+ return {
100
+ role,
101
+ address: account,
102
+ hasRole: result
103
+ };
104
+ }
105
+ /**
106
+ * Check if address is blacklisted
107
+ */
108
+ async isBlacklisted(account) {
109
+ (0, import_djeon402_core.validateAddress)(account);
110
+ const isBlacklisted = await this.sdk.publicClient.readContract({
111
+ address: this.sdk.contractAddress,
112
+ abi: import_djeon402_core.DJEON402_ABI,
113
+ functionName: "isBlacklisted",
114
+ args: [account]
115
+ });
116
+ return {
117
+ isBlacklisted,
118
+ address: account
119
+ };
120
+ }
121
+ /**
122
+ * Blacklist an address
123
+ */
124
+ async blacklist(params) {
125
+ const { walletClient, account } = params;
126
+ if (!walletClient.account) {
127
+ throw new Error("Wallet client must have an account");
128
+ }
129
+ (0, import_djeon402_core.validateAddress)(account);
130
+ const hash = await walletClient.writeContract({
131
+ address: this.sdk.contractAddress,
132
+ abi: import_djeon402_core.DJEON402_ABI,
133
+ functionName: "blacklist",
134
+ args: [account],
135
+ account: walletClient.account,
136
+ chain: walletClient.chain
137
+ });
138
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
139
+ return {
140
+ success: receipt.status === "success",
141
+ hash,
142
+ blockNumber: receipt.blockNumber.toString()
143
+ };
144
+ }
145
+ /**
146
+ * Remove from blacklist
147
+ */
148
+ async unBlacklist(params) {
149
+ const { walletClient, account } = params;
150
+ if (!walletClient.account) {
151
+ throw new Error("Wallet client must have an account");
152
+ }
153
+ (0, import_djeon402_core.validateAddress)(account);
154
+ const hash = await walletClient.writeContract({
155
+ address: this.sdk.contractAddress,
156
+ abi: import_djeon402_core.DJEON402_ABI,
157
+ functionName: "unBlacklist",
158
+ args: [account],
159
+ account: walletClient.account,
160
+ chain: walletClient.chain
161
+ });
162
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
163
+ return {
164
+ success: receipt.status === "success",
165
+ hash,
166
+ blockNumber: receipt.blockNumber.toString()
167
+ };
168
+ }
169
+ /**
170
+ * Pause contract
171
+ */
172
+ async pause(params) {
173
+ const { walletClient } = params;
174
+ if (!walletClient.account) {
175
+ throw new Error("Wallet client must have an account");
176
+ }
177
+ const hash = await walletClient.writeContract({
178
+ address: this.sdk.contractAddress,
179
+ abi: import_djeon402_core.DJEON402_ABI,
180
+ functionName: "pause",
181
+ account: walletClient.account,
182
+ chain: walletClient.chain
183
+ });
184
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
185
+ return {
186
+ success: receipt.status === "success",
187
+ hash,
188
+ blockNumber: receipt.blockNumber.toString()
189
+ };
190
+ }
191
+ /**
192
+ * Unpause contract
193
+ */
194
+ async unpause(params) {
195
+ const { walletClient } = params;
196
+ if (!walletClient.account) {
197
+ throw new Error("Wallet client must have an account");
198
+ }
199
+ const hash = await walletClient.writeContract({
200
+ address: this.sdk.contractAddress,
201
+ abi: import_djeon402_core.DJEON402_ABI,
202
+ functionName: "unpause",
203
+ account: walletClient.account,
204
+ chain: walletClient.chain
205
+ });
206
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
207
+ return {
208
+ success: receipt.status === "success",
209
+ hash,
210
+ blockNumber: receipt.blockNumber.toString()
211
+ };
212
+ }
213
+ };
214
+
215
+ // src/modules/kyc.ts
216
+ var import_djeon402_core2 = require("@bbuilders/djeon402-core");
217
+ var KYCModule = class {
218
+ constructor(sdk) {
219
+ this.sdk = sdk;
220
+ }
221
+ /**
222
+ * Get KYC data for an address
223
+ */
224
+ async getData(address) {
225
+ if (!this.sdk.kycRegistryAddress) {
226
+ throw new Error("KYC Registry address not configured");
227
+ }
228
+ (0, import_djeon402_core2.validateAddress)(address);
229
+ const kycData = await this.sdk.publicClient.readContract({
230
+ address: this.sdk.kycRegistryAddress,
231
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
232
+ functionName: "getKYCData",
233
+ args: [address]
234
+ });
235
+ const result = kycData;
236
+ const [level, expiryDate, kycHash, isActive, dailyLimit, dailySpent] = result;
237
+ const levelNames = ["None", "Tier1", "Tier2", "Tier3"];
238
+ const expiryDateReadable = new Date(Number(expiryDate) * 1e3).toISOString();
239
+ return {
240
+ level,
241
+ levelName: levelNames[level],
242
+ expiryDate: Number(expiryDate),
243
+ expiryDateReadable,
244
+ kycHash,
245
+ isActive,
246
+ dailyLimit: dailyLimit.toString(),
247
+ dailyLimitRaw: dailyLimit.toString(),
248
+ dailySpent: dailySpent.toString(),
249
+ dailySpentRaw: dailySpent.toString(),
250
+ userAddress: address
251
+ };
252
+ }
253
+ /**
254
+ * Get remaining daily limit
255
+ */
256
+ async getRemainingLimit(address) {
257
+ if (!this.sdk.kycRegistryAddress) {
258
+ throw new Error("KYC Registry address not configured");
259
+ }
260
+ (0, import_djeon402_core2.validateAddress)(address);
261
+ const remaining = await this.sdk.publicClient.readContract({
262
+ address: this.sdk.kycRegistryAddress,
263
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
264
+ functionName: "getRemainingDailyLimit",
265
+ args: [address]
266
+ });
267
+ return {
268
+ address,
269
+ remainingLimit: remaining.toString()
270
+ };
271
+ }
272
+ /**
273
+ * Verify KYC (admin only)
274
+ */
275
+ async verify(params) {
276
+ if (!this.sdk.kycRegistryAddress) {
277
+ throw new Error("KYC Registry address not configured");
278
+ }
279
+ const { walletClient, userAddress, level, expiryDate, documentHash } = params;
280
+ if (!walletClient.account) {
281
+ throw new Error("Wallet client must have an account");
282
+ }
283
+ (0, import_djeon402_core2.validateAddress)(userAddress);
284
+ if (level < 0 || level > 3) {
285
+ throw new Error("Invalid KYC level. Must be 0-3");
286
+ }
287
+ const hash = await walletClient.writeContract({
288
+ address: this.sdk.kycRegistryAddress,
289
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
290
+ functionName: "verifyKYC",
291
+ args: [userAddress, level, BigInt(expiryDate), documentHash],
292
+ account: walletClient.account,
293
+ chain: walletClient.chain
294
+ });
295
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
296
+ return {
297
+ success: receipt.status === "success",
298
+ hash,
299
+ blockNumber: receipt.blockNumber.toString()
300
+ };
301
+ }
302
+ /**
303
+ * Update KYC level (admin only)
304
+ */
305
+ async updateKYC(params) {
306
+ if (!this.sdk.kycRegistryAddress) {
307
+ throw new Error("KYC Registry address not configured");
308
+ }
309
+ const { walletClient, userAddress, level, expiryDate = 0 } = params;
310
+ if (!walletClient.account) {
311
+ throw new Error("Wallet client must have an account");
312
+ }
313
+ (0, import_djeon402_core2.validateAddress)(userAddress);
314
+ const hash = await walletClient.writeContract({
315
+ address: this.sdk.kycRegistryAddress,
316
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
317
+ functionName: "updateKYC",
318
+ args: [userAddress, level, BigInt(expiryDate)],
319
+ account: walletClient.account,
320
+ chain: walletClient.chain
321
+ });
322
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
323
+ return {
324
+ success: receipt.status === "success",
325
+ hash,
326
+ blockNumber: receipt.blockNumber.toString()
327
+ };
328
+ }
329
+ /**
330
+ * Revoke KYC (admin only)
331
+ */
332
+ async revokeKYC(params) {
333
+ if (!this.sdk.kycRegistryAddress) {
334
+ throw new Error("KYC Registry address not configured");
335
+ }
336
+ const { walletClient, userAddress } = params;
337
+ if (!walletClient.account) {
338
+ throw new Error("Wallet client must have an account");
339
+ }
340
+ (0, import_djeon402_core2.validateAddress)(userAddress);
341
+ const hash = await walletClient.writeContract({
342
+ address: this.sdk.kycRegistryAddress,
343
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
344
+ functionName: "revokeKYC",
345
+ args: [userAddress],
346
+ account: walletClient.account,
347
+ chain: walletClient.chain
348
+ });
349
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
350
+ return {
351
+ success: receipt.status === "success",
352
+ hash,
353
+ blockNumber: receipt.blockNumber.toString()
354
+ };
355
+ }
356
+ /**
357
+ * Set daily limit for a user (admin only)
358
+ */
359
+ async setDailyLimit(params) {
360
+ if (!this.sdk.kycRegistryAddress) {
361
+ throw new Error("KYC Registry address not configured");
362
+ }
363
+ const { walletClient, userAddress, limitUSD } = params;
364
+ if (!walletClient.account) {
365
+ throw new Error("Wallet client must have an account");
366
+ }
367
+ (0, import_djeon402_core2.validateAddress)(userAddress);
368
+ const limitInSmallestUnit = BigInt(parseFloat(limitUSD) * 1e6);
369
+ const hash = await walletClient.writeContract({
370
+ address: this.sdk.kycRegistryAddress,
371
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
372
+ functionName: "setDailyLimit",
373
+ args: [userAddress, limitInSmallestUnit],
374
+ account: walletClient.account,
375
+ chain: walletClient.chain
376
+ });
377
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
378
+ return {
379
+ success: receipt.status === "success",
380
+ hash,
381
+ blockNumber: receipt.blockNumber.toString()
382
+ };
383
+ }
384
+ /**
385
+ * Check if a transaction amount is within the user's daily limit
386
+ */
387
+ async checkDailyLimit(params) {
388
+ if (!this.sdk.kycRegistryAddress) {
389
+ throw new Error("KYC Registry address not configured");
390
+ }
391
+ const { walletClient, userAddress, amountUSD } = params;
392
+ if (!walletClient.account) {
393
+ throw new Error("Wallet client must have an account");
394
+ }
395
+ (0, import_djeon402_core2.validateAddress)(userAddress);
396
+ const amountInSmallestUnit = BigInt(parseFloat(amountUSD) * 1e6);
397
+ const result = await walletClient.writeContract({
398
+ address: this.sdk.kycRegistryAddress,
399
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
400
+ functionName: "checkDailyLimit",
401
+ args: [userAddress, amountInSmallestUnit],
402
+ account: walletClient.account,
403
+ chain: walletClient.chain
404
+ });
405
+ return result;
406
+ }
407
+ /**
408
+ * Check if a user's KYC is valid (view)
409
+ */
410
+ async isKYCValid(userAddress) {
411
+ if (!this.sdk.kycRegistryAddress) {
412
+ throw new Error("KYC Registry address not configured");
413
+ }
414
+ (0, import_djeon402_core2.validateAddress)(userAddress);
415
+ const result = await this.sdk.publicClient.readContract({
416
+ address: this.sdk.kycRegistryAddress,
417
+ abi: import_djeon402_core2.KYC_REGISTRY_ABI,
418
+ functionName: "isKYCValid",
419
+ args: [userAddress]
420
+ });
421
+ return result;
422
+ }
423
+ };
424
+
425
+ // src/modules/token.ts
426
+ var import_djeon402_core3 = require("@bbuilders/djeon402-core");
427
+ var TokenModule = class {
428
+ constructor(sdk) {
429
+ this.sdk = sdk;
430
+ }
431
+ /**
432
+ * Get token information
433
+ */
434
+ async getInfo() {
435
+ const [name, symbol, decimals, totalSupply, paused] = await Promise.all([
436
+ this.sdk.publicClient.readContract({
437
+ address: this.sdk.contractAddress,
438
+ abi: import_djeon402_core3.DJEON402_ABI,
439
+ functionName: "name"
440
+ }),
441
+ this.sdk.publicClient.readContract({
442
+ address: this.sdk.contractAddress,
443
+ abi: import_djeon402_core3.DJEON402_ABI,
444
+ functionName: "symbol"
445
+ }),
446
+ this.sdk.publicClient.readContract({
447
+ address: this.sdk.contractAddress,
448
+ abi: import_djeon402_core3.DJEON402_ABI,
449
+ functionName: "decimals"
450
+ }),
451
+ this.sdk.publicClient.readContract({
452
+ address: this.sdk.contractAddress,
453
+ abi: import_djeon402_core3.DJEON402_ABI,
454
+ functionName: "totalSupply"
455
+ }),
456
+ this.sdk.publicClient.readContract({
457
+ address: this.sdk.contractAddress,
458
+ abi: import_djeon402_core3.DJEON402_ABI,
459
+ functionName: "paused"
460
+ })
461
+ ]);
462
+ return {
463
+ name,
464
+ symbol,
465
+ decimals,
466
+ totalSupply: (0, import_djeon402_core3.formatTokenAmount)(totalSupply, decimals),
467
+ totalSupplyRaw: totalSupply.toString(),
468
+ paused,
469
+ contractAddress: this.sdk.contractAddress
470
+ };
471
+ }
472
+ /**
473
+ * Get balance of an address
474
+ */
475
+ async getBalance(address) {
476
+ (0, import_djeon402_core3.validateAddress)(address);
477
+ const [balance, decimals] = await Promise.all([
478
+ this.sdk.publicClient.readContract({
479
+ address: this.sdk.contractAddress,
480
+ abi: import_djeon402_core3.DJEON402_ABI,
481
+ functionName: "balanceOf",
482
+ args: [address]
483
+ }),
484
+ this.sdk.publicClient.readContract({
485
+ address: this.sdk.contractAddress,
486
+ abi: import_djeon402_core3.DJEON402_ABI,
487
+ functionName: "decimals"
488
+ })
489
+ ]);
490
+ return {
491
+ address,
492
+ balance: (0, import_djeon402_core3.formatTokenAmount)(balance, decimals),
493
+ balanceRaw: balance.toString()
494
+ };
495
+ }
496
+ /**
497
+ * Get allowance
498
+ */
499
+ async getAllowance(owner, spender) {
500
+ (0, import_djeon402_core3.validateAddress)(owner);
501
+ (0, import_djeon402_core3.validateAddress)(spender);
502
+ const [allowance, decimals] = await Promise.all([
503
+ this.sdk.publicClient.readContract({
504
+ address: this.sdk.contractAddress,
505
+ abi: import_djeon402_core3.DJEON402_ABI,
506
+ functionName: "allowance",
507
+ args: [owner, spender]
508
+ }),
509
+ this.sdk.publicClient.readContract({
510
+ address: this.sdk.contractAddress,
511
+ abi: import_djeon402_core3.DJEON402_ABI,
512
+ functionName: "decimals"
513
+ })
514
+ ]);
515
+ return {
516
+ owner,
517
+ spender,
518
+ allowance: (0, import_djeon402_core3.formatTokenAmount)(allowance, decimals),
519
+ allowanceRaw: allowance.toString()
520
+ };
521
+ }
522
+ /**
523
+ * Transfer tokens using wallet client
524
+ */
525
+ async transfer(params) {
526
+ const { walletClient, to, amount } = params;
527
+ if (!walletClient.account) {
528
+ throw new Error("Wallet client must have an account");
529
+ }
530
+ (0, import_djeon402_core3.validateAddress)(to);
531
+ (0, import_djeon402_core3.validateAmount)(amount);
532
+ const decimals = await this.sdk.publicClient.readContract({
533
+ address: this.sdk.contractAddress,
534
+ abi: import_djeon402_core3.DJEON402_ABI,
535
+ functionName: "decimals"
536
+ });
537
+ const amountBigInt = (0, import_djeon402_core3.parseTokenAmount)(amount, decimals);
538
+ const hash = await walletClient.writeContract({
539
+ address: this.sdk.contractAddress,
540
+ abi: import_djeon402_core3.DJEON402_ABI,
541
+ functionName: "transfer",
542
+ args: [to, amountBigInt],
543
+ account: walletClient.account,
544
+ chain: walletClient.chain
545
+ });
546
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({
547
+ hash
548
+ });
549
+ return {
550
+ success: receipt.status === "success",
551
+ hash,
552
+ from: walletClient.account.address,
553
+ to,
554
+ amount,
555
+ amountRaw: amountBigInt.toString(),
556
+ blockNumber: receipt.blockNumber.toString(),
557
+ status: receipt.status
558
+ };
559
+ }
560
+ /**
561
+ * Approve spending
562
+ */
563
+ async approve(params) {
564
+ const { walletClient, spender, amount } = params;
565
+ if (!walletClient.account) {
566
+ throw new Error("Wallet client must have an account");
567
+ }
568
+ (0, import_djeon402_core3.validateAddress)(spender);
569
+ (0, import_djeon402_core3.validateAmount)(amount);
570
+ const decimals = await this.sdk.publicClient.readContract({
571
+ address: this.sdk.contractAddress,
572
+ abi: import_djeon402_core3.DJEON402_ABI,
573
+ functionName: "decimals"
574
+ });
575
+ const amountBigInt = (0, import_djeon402_core3.parseTokenAmount)(amount, decimals);
576
+ const hash = await walletClient.writeContract({
577
+ address: this.sdk.contractAddress,
578
+ abi: import_djeon402_core3.DJEON402_ABI,
579
+ functionName: "approve",
580
+ args: [spender, amountBigInt],
581
+ account: walletClient.account,
582
+ chain: walletClient.chain
583
+ });
584
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
585
+ return {
586
+ success: receipt.status === "success",
587
+ hash,
588
+ blockNumber: receipt.blockNumber.toString()
589
+ };
590
+ }
591
+ /**
592
+ * Mint tokens (requires MINTER_ROLE)
593
+ */
594
+ async mint(params) {
595
+ const { walletClient, to, amount } = params;
596
+ if (!walletClient.account) {
597
+ throw new Error("Wallet client must have an account");
598
+ }
599
+ (0, import_djeon402_core3.validateAddress)(to);
600
+ (0, import_djeon402_core3.validateAmount)(amount);
601
+ const decimals = await this.sdk.publicClient.readContract({
602
+ address: this.sdk.contractAddress,
603
+ abi: import_djeon402_core3.DJEON402_ABI,
604
+ functionName: "decimals"
605
+ });
606
+ const amountBigInt = (0, import_djeon402_core3.parseTokenAmount)(amount, decimals);
607
+ const hash = await walletClient.writeContract({
608
+ address: this.sdk.contractAddress,
609
+ abi: import_djeon402_core3.DJEON402_ABI,
610
+ functionName: "mint",
611
+ args: [to, amountBigInt],
612
+ account: walletClient.account,
613
+ chain: walletClient.chain
614
+ });
615
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
616
+ return {
617
+ success: receipt.status === "success",
618
+ hash,
619
+ blockNumber: receipt.blockNumber.toString()
620
+ };
621
+ }
622
+ /**
623
+ * Burn tokens (requires BURNER_ROLE)
624
+ */
625
+ async burn(params) {
626
+ const { walletClient, amount } = params;
627
+ if (!walletClient.account) {
628
+ throw new Error("Wallet client must have an account");
629
+ }
630
+ (0, import_djeon402_core3.validateAmount)(amount);
631
+ const decimals = await this.sdk.publicClient.readContract({
632
+ address: this.sdk.contractAddress,
633
+ abi: import_djeon402_core3.DJEON402_ABI,
634
+ functionName: "decimals"
635
+ });
636
+ const amountBigInt = (0, import_djeon402_core3.parseTokenAmount)(amount, decimals);
637
+ const hash = await walletClient.writeContract({
638
+ address: this.sdk.contractAddress,
639
+ abi: import_djeon402_core3.DJEON402_ABI,
640
+ functionName: "burn",
641
+ args: [amountBigInt],
642
+ account: walletClient.account,
643
+ chain: walletClient.chain
644
+ });
645
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
646
+ return {
647
+ success: receipt.status === "success",
648
+ hash,
649
+ blockNumber: receipt.blockNumber.toString()
650
+ };
651
+ }
652
+ };
653
+
654
+ // src/modules/x402.ts
655
+ var import_djeon402_core4 = require("@bbuilders/djeon402-core");
656
+ var X402Module = class {
657
+ constructor(sdk) {
658
+ this.sdk = sdk;
659
+ }
660
+ /**
661
+ * Generate a random nonce
662
+ */
663
+ generateNonce() {
664
+ const randomBytes = new Uint8Array(32);
665
+ crypto.getRandomValues(randomBytes);
666
+ return `0x${Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
667
+ }
668
+ /**
669
+ * Get EIP-712 domain separator
670
+ */
671
+ async getDomainSeparator() {
672
+ const domain = await this.sdk.publicClient.readContract({
673
+ address: this.sdk.contractAddress,
674
+ abi: import_djeon402_core4.DJEON402_ABI,
675
+ functionName: "DOMAIN_SEPARATOR"
676
+ });
677
+ return domain;
678
+ }
679
+ /**
680
+ * Get authorization state (whether a nonce has been used)
681
+ */
682
+ async getAuthorizationState(authorizer, nonce) {
683
+ return await this.sdk.publicClient.readContract({
684
+ address: this.sdk.contractAddress,
685
+ abi: import_djeon402_core4.DJEON402_ABI,
686
+ functionName: "authorizationState",
687
+ args: [authorizer, nonce]
688
+ });
689
+ }
690
+ /**
691
+ * Sign transfer authorization using wallet
692
+ */
693
+ async signTransferWithWallet(params) {
694
+ const { walletClient, to, amount, validAfter = 0n, validBefore, nonce } = params;
695
+ if (!walletClient.account) {
696
+ throw new Error("Wallet client must have an account");
697
+ }
698
+ (0, import_djeon402_core4.validateAddress)(to);
699
+ (0, import_djeon402_core4.validateAmount)(amount);
700
+ const from = walletClient.account.address;
701
+ const decimals = await this.sdk.publicClient.readContract({
702
+ address: this.sdk.contractAddress,
703
+ abi: import_djeon402_core4.DJEON402_ABI,
704
+ functionName: "decimals"
705
+ });
706
+ const value = (0, import_djeon402_core4.parseTokenAmount)(amount, decimals);
707
+ const transferNonce = nonce || this.generateNonce();
708
+ const validBeforeTimestamp = validBefore ?? BigInt(Math.floor(Date.now() / 1e3) + 3600);
709
+ const name = await this.sdk.publicClient.readContract({
710
+ address: this.sdk.contractAddress,
711
+ abi: import_djeon402_core4.DJEON402_ABI,
712
+ functionName: "name"
713
+ });
714
+ const domain = {
715
+ name,
716
+ version: "1",
717
+ chainId: this.sdk.chainId,
718
+ verifyingContract: this.sdk.contractAddress
719
+ };
720
+ const types = {
721
+ TransferWithAuthorization: [
722
+ { name: "from", type: "address" },
723
+ { name: "to", type: "address" },
724
+ { name: "value", type: "uint256" },
725
+ { name: "validAfter", type: "uint256" },
726
+ { name: "validBefore", type: "uint256" },
727
+ { name: "nonce", type: "bytes32" }
728
+ ]
729
+ };
730
+ const message = {
731
+ from,
732
+ to,
733
+ value,
734
+ validAfter,
735
+ validBefore: validBeforeTimestamp,
736
+ nonce: transferNonce
737
+ };
738
+ const signature = await walletClient.signTypedData({
739
+ account: walletClient.account,
740
+ domain,
741
+ types,
742
+ primaryType: "TransferWithAuthorization",
743
+ message
744
+ });
745
+ const v = parseInt(signature.slice(130, 132), 16);
746
+ const r = `0x${signature.slice(2, 66)}`;
747
+ const s = `0x${signature.slice(66, 130)}`;
748
+ return {
749
+ from,
750
+ to,
751
+ value,
752
+ validAfter,
753
+ validBefore: validBeforeTimestamp,
754
+ nonce: transferNonce,
755
+ v,
756
+ r,
757
+ s
758
+ };
759
+ }
760
+ /**
761
+ * Sign receive authorization using wallet (receiver signs)
762
+ */
763
+ async signReceiveWithWallet(params) {
764
+ const { walletClient, from, amount, validAfter = 0n, validBefore, nonce } = params;
765
+ if (!walletClient.account) {
766
+ throw new Error("Wallet client must have an account");
767
+ }
768
+ (0, import_djeon402_core4.validateAddress)(from);
769
+ (0, import_djeon402_core4.validateAmount)(amount);
770
+ const to = walletClient.account.address;
771
+ const decimals = await this.sdk.publicClient.readContract({
772
+ address: this.sdk.contractAddress,
773
+ abi: import_djeon402_core4.DJEON402_ABI,
774
+ functionName: "decimals"
775
+ });
776
+ const value = (0, import_djeon402_core4.parseTokenAmount)(amount, decimals);
777
+ const receiveNonce = nonce || this.generateNonce();
778
+ const validBeforeTimestamp = validBefore ?? BigInt(Math.floor(Date.now() / 1e3) + 3600);
779
+ const name = await this.sdk.publicClient.readContract({
780
+ address: this.sdk.contractAddress,
781
+ abi: import_djeon402_core4.DJEON402_ABI,
782
+ functionName: "name"
783
+ });
784
+ const domain = {
785
+ name,
786
+ version: "1",
787
+ chainId: this.sdk.chainId,
788
+ verifyingContract: this.sdk.contractAddress
789
+ };
790
+ const types = {
791
+ ReceiveWithAuthorization: [
792
+ { name: "from", type: "address" },
793
+ { name: "to", type: "address" },
794
+ { name: "value", type: "uint256" },
795
+ { name: "validAfter", type: "uint256" },
796
+ { name: "validBefore", type: "uint256" },
797
+ { name: "nonce", type: "bytes32" }
798
+ ]
799
+ };
800
+ const message = {
801
+ from,
802
+ to,
803
+ value,
804
+ validAfter,
805
+ validBefore: validBeforeTimestamp,
806
+ nonce: receiveNonce
807
+ };
808
+ const signature = await walletClient.signTypedData({
809
+ account: walletClient.account,
810
+ domain,
811
+ types,
812
+ primaryType: "ReceiveWithAuthorization",
813
+ message
814
+ });
815
+ const v = parseInt(signature.slice(130, 132), 16);
816
+ const r = `0x${signature.slice(2, 66)}`;
817
+ const s = `0x${signature.slice(66, 130)}`;
818
+ return {
819
+ from,
820
+ to,
821
+ value,
822
+ validAfter,
823
+ validBefore: validBeforeTimestamp,
824
+ nonce: receiveNonce,
825
+ v,
826
+ r,
827
+ s
828
+ };
829
+ }
830
+ /**
831
+ * Execute receive with authorization (caller must be the receiver)
832
+ */
833
+ async executeReceive(params) {
834
+ const { walletClient, authorization } = params;
835
+ if (!walletClient.account) {
836
+ throw new Error("Wallet client must have an account");
837
+ }
838
+ const { from, to, value, validAfter, validBefore, nonce, v, r, s } = authorization;
839
+ const hash = await walletClient.writeContract({
840
+ address: this.sdk.contractAddress,
841
+ abi: import_djeon402_core4.DJEON402_ABI,
842
+ functionName: "receiveWithAuthorization",
843
+ args: [from, to, value, validAfter, validBefore, nonce, v, r, s],
844
+ account: walletClient.account,
845
+ chain: walletClient.chain
846
+ });
847
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
848
+ return {
849
+ success: receipt.status === "success",
850
+ hash,
851
+ blockNumber: receipt.blockNumber.toString()
852
+ };
853
+ }
854
+ /**
855
+ * Sign cancel authorization using wallet
856
+ */
857
+ async signCancelWithWallet(params) {
858
+ const { walletClient, authorizer, nonce: authNonce } = params;
859
+ if (!walletClient.account) {
860
+ throw new Error("Wallet client must have an account");
861
+ }
862
+ const name = await this.sdk.publicClient.readContract({
863
+ address: this.sdk.contractAddress,
864
+ abi: import_djeon402_core4.DJEON402_ABI,
865
+ functionName: "name"
866
+ });
867
+ const domain = {
868
+ name,
869
+ version: "1",
870
+ chainId: this.sdk.chainId,
871
+ verifyingContract: this.sdk.contractAddress
872
+ };
873
+ const types = {
874
+ CancelAuthorization: [
875
+ { name: "authorizer", type: "address" },
876
+ { name: "nonce", type: "bytes32" }
877
+ ]
878
+ };
879
+ const message = { authorizer, nonce: authNonce };
880
+ const signature = await walletClient.signTypedData({
881
+ account: walletClient.account,
882
+ domain,
883
+ types,
884
+ primaryType: "CancelAuthorization",
885
+ message
886
+ });
887
+ const v = parseInt(signature.slice(130, 132), 16);
888
+ const r = `0x${signature.slice(2, 66)}`;
889
+ const s = `0x${signature.slice(66, 130)}`;
890
+ return { authorizer, nonce: authNonce, v, r, s };
891
+ }
892
+ /**
893
+ * Cancel an authorization (marks nonce as used)
894
+ */
895
+ async cancelAuthorization(params) {
896
+ const { walletClient } = params;
897
+ const { authorizer, nonce, v, r, s } = await this.signCancelWithWallet(params);
898
+ const hash = await walletClient.writeContract({
899
+ address: this.sdk.contractAddress,
900
+ abi: import_djeon402_core4.DJEON402_ABI,
901
+ functionName: "cancelAuthorization",
902
+ args: [authorizer, nonce, v, r, s],
903
+ account: walletClient.account,
904
+ chain: walletClient.chain
905
+ });
906
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
907
+ return {
908
+ success: receipt.status === "success",
909
+ hash,
910
+ blockNumber: receipt.blockNumber.toString()
911
+ };
912
+ }
913
+ /**
914
+ * Execute transfer with authorization (relayer function)
915
+ */
916
+ async executeTransfer(params) {
917
+ const { walletClient, authorization } = params;
918
+ if (!walletClient.account) {
919
+ throw new Error("Wallet client must have an account");
920
+ }
921
+ const { from, to, value, validAfter, validBefore, nonce, v, r, s } = authorization;
922
+ const hash = await walletClient.writeContract({
923
+ address: this.sdk.contractAddress,
924
+ abi: import_djeon402_core4.DJEON402_ABI,
925
+ functionName: "transferWithAuthorization",
926
+ args: [from, to, value, validAfter, validBefore, nonce, v, r, s],
927
+ account: walletClient.account,
928
+ chain: walletClient.chain
929
+ });
930
+ const receipt = await this.sdk.publicClient.waitForTransactionReceipt({ hash });
931
+ return {
932
+ success: receipt.status === "success",
933
+ hash,
934
+ blockNumber: receipt.blockNumber.toString()
935
+ };
936
+ }
937
+ /**
938
+ * Fetch wrapper that auto-handles 402 Payment Required responses.
939
+ * On 402, decodes PAYMENT-REQUIRED header, signs authorization, retries with PAYMENT-SIGNATURE.
940
+ */
941
+ async fetchWithPayment(walletClient, url, options = {}) {
942
+ const response = await fetch(url, options);
943
+ if (response.status !== 402) return response;
944
+ const paymentRequiredHeader = response.headers.get("PAYMENT-REQUIRED");
945
+ if (!paymentRequiredHeader) {
946
+ throw new Error("402 response missing PAYMENT-REQUIRED header");
947
+ }
948
+ const paymentRequired = JSON.parse(atob(paymentRequiredHeader));
949
+ const accepted = paymentRequired.accepts?.[0];
950
+ if (!accepted) {
951
+ throw new Error("No accepted payment methods in 402 response");
952
+ }
953
+ const authData = await this.signTransferWithWallet({
954
+ walletClient,
955
+ to: accepted.payTo,
956
+ amount: accepted.amount
957
+ });
958
+ const paymentPayload = {
959
+ x402Version: paymentRequired.x402Version || 2,
960
+ resource: paymentRequired.resource,
961
+ accepted,
962
+ payload: {
963
+ signature: `0x${authData.r.slice(2)}${authData.s.slice(2)}${authData.v.toString(16).padStart(2, "0")}`,
964
+ authorization: {
965
+ from: authData.from,
966
+ to: authData.to,
967
+ value: authData.value.toString(),
968
+ validAfter: authData.validAfter.toString(),
969
+ validBefore: authData.validBefore.toString(),
970
+ nonce: authData.nonce
971
+ }
972
+ }
973
+ };
974
+ const encoded = btoa(JSON.stringify(paymentPayload));
975
+ return fetch(url, {
976
+ ...options,
977
+ headers: {
978
+ ...Object.fromEntries(new Headers(options.headers).entries()),
979
+ "PAYMENT-SIGNATURE": encoded
980
+ }
981
+ });
982
+ }
983
+ };
984
+
985
+ // src/client.ts
986
+ var Djeon402ClientSDK = class {
987
+ constructor(config) {
988
+ const { rpcUrl, contractAddress, kycRegistryAddress, chainId } = config;
989
+ this.contractAddress = contractAddress;
990
+ this.kycRegistryAddress = kycRegistryAddress;
991
+ this.chainId = chainId;
992
+ const chain = chainId === 8453 ? import_chains.base : {
993
+ id: chainId,
994
+ name: "Custom Chain",
995
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
996
+ rpcUrls: {
997
+ default: { http: [rpcUrl || ""] },
998
+ public: { http: [rpcUrl || ""] }
999
+ }
1000
+ };
1001
+ this.publicClient = (0, import_viem.createPublicClient)({
1002
+ chain,
1003
+ transport: (0, import_viem.http)(rpcUrl)
1004
+ });
1005
+ this.token = new TokenModule(this);
1006
+ this.admin = new AdminModule(this);
1007
+ this.kyc = new KYCModule(this);
1008
+ this.x402 = new X402Module(this);
1009
+ }
1010
+ /**
1011
+ * Get chain configuration
1012
+ */
1013
+ getChain() {
1014
+ return this.chainId === 8453 ? import_chains.base : {
1015
+ id: this.chainId,
1016
+ name: "Custom Chain",
1017
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
1018
+ rpcUrls: {
1019
+ default: { http: [this.publicClient.transport.url || ""] },
1020
+ public: { http: [this.publicClient.transport.url || ""] }
1021
+ }
1022
+ };
1023
+ }
1024
+ };
1025
+
1026
+ // src/react/provider.tsx
1027
+ var import_jsx_runtime = require("react/jsx-runtime");
1028
+ var Djeon402Context = (0, import_react.createContext)(null);
1029
+ function Djeon402Provider({
1030
+ children,
1031
+ config
1032
+ }) {
1033
+ const sdk = (0, import_react.useMemo)(() => {
1034
+ return new Djeon402ClientSDK({
1035
+ contractAddress: config.contractAddress,
1036
+ kycRegistryAddress: config.kycRegistryAddress,
1037
+ chainId: config.chainId,
1038
+ rpcUrl: config.rpcUrl || ""
1039
+ });
1040
+ }, [config.contractAddress, config.kycRegistryAddress, config.chainId, config.rpcUrl]);
1041
+ const value = (0, import_react.useMemo)(() => ({ sdk, config }), [sdk, config]);
1042
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Djeon402Context.Provider, { value, children });
1043
+ }
1044
+ function useDjeon402() {
1045
+ const context = (0, import_react.useContext)(Djeon402Context);
1046
+ if (!context) {
1047
+ throw new Error("useDjeon402 must be used within Djeon402Provider");
1048
+ }
1049
+ return context;
1050
+ }
1051
+
1052
+ // src/react/useApprove.ts
1053
+ var import_react_query = require("@tanstack/react-query");
1054
+ var import_wagmi = require("wagmi");
1055
+ function useApprove() {
1056
+ const { sdk } = useDjeon402();
1057
+ const { data: walletClient } = (0, import_wagmi.useWalletClient)();
1058
+ const queryClient = (0, import_react_query.useQueryClient)();
1059
+ const mutation = (0, import_react_query.useMutation)({
1060
+ mutationFn: async ({ spender, amount }) => {
1061
+ if (!walletClient) {
1062
+ throw new Error("Wallet not connected");
1063
+ }
1064
+ return sdk.token.approve({ walletClient, spender, amount });
1065
+ },
1066
+ onSuccess: () => {
1067
+ queryClient.invalidateQueries({ queryKey: ["djeon402", "allowance"] });
1068
+ }
1069
+ });
1070
+ return {
1071
+ approve: mutation.mutateAsync,
1072
+ isLoading: mutation.isPending,
1073
+ isSuccess: mutation.isSuccess,
1074
+ error: mutation.error,
1075
+ data: mutation.data
1076
+ };
1077
+ }
1078
+
1079
+ // src/react/useBalance.ts
1080
+ var import_react_query2 = require("@tanstack/react-query");
1081
+ function useBalance(address) {
1082
+ const { sdk } = useDjeon402();
1083
+ return (0, import_react_query2.useQuery)({
1084
+ queryKey: ["djeon402", "balance", sdk.contractAddress, address],
1085
+ queryFn: () => {
1086
+ if (!address) throw new Error("Address is required");
1087
+ return sdk.token.getBalance(address);
1088
+ },
1089
+ enabled: !!address,
1090
+ staleTime: 1e4
1091
+ // 10 seconds
1092
+ });
1093
+ }
1094
+
1095
+ // src/react/useIsBlacklisted.ts
1096
+ var import_react_query3 = require("@tanstack/react-query");
1097
+ function useIsBlacklisted(address) {
1098
+ const { sdk } = useDjeon402();
1099
+ return (0, import_react_query3.useQuery)({
1100
+ queryKey: ["djeon402", "blacklist", sdk.contractAddress, address],
1101
+ queryFn: () => {
1102
+ if (!address) throw new Error("Address is required");
1103
+ return sdk.admin.isBlacklisted(address);
1104
+ },
1105
+ enabled: !!address,
1106
+ staleTime: 3e4
1107
+ // 30 seconds
1108
+ });
1109
+ }
1110
+
1111
+ // src/react/useKYCData.ts
1112
+ var import_react_query4 = require("@tanstack/react-query");
1113
+ function useKYCData(address) {
1114
+ const { sdk } = useDjeon402();
1115
+ return (0, import_react_query4.useQuery)({
1116
+ queryKey: ["djeon402", "kyc", sdk.kycRegistryAddress, address],
1117
+ queryFn: () => {
1118
+ if (!address) throw new Error("Address is required");
1119
+ return sdk.kyc.getData(address);
1120
+ },
1121
+ enabled: !!address && !!sdk.kycRegistryAddress,
1122
+ staleTime: 3e4
1123
+ // 30 seconds
1124
+ });
1125
+ }
1126
+
1127
+ // src/react/useTokenInfo.ts
1128
+ var import_react_query5 = require("@tanstack/react-query");
1129
+ function useTokenInfo() {
1130
+ const { sdk } = useDjeon402();
1131
+ return (0, import_react_query5.useQuery)({
1132
+ queryKey: ["djeon402", "tokenInfo", sdk.contractAddress],
1133
+ queryFn: () => sdk.token.getInfo(),
1134
+ staleTime: 6e4
1135
+ // 1 minute
1136
+ });
1137
+ }
1138
+
1139
+ // src/react/useTransfer.ts
1140
+ var import_react_query6 = require("@tanstack/react-query");
1141
+ var import_wagmi2 = require("wagmi");
1142
+ function useTransfer() {
1143
+ const { sdk } = useDjeon402();
1144
+ const { data: walletClient } = (0, import_wagmi2.useWalletClient)();
1145
+ const queryClient = (0, import_react_query6.useQueryClient)();
1146
+ const mutation = (0, import_react_query6.useMutation)({
1147
+ mutationFn: async ({ to, amount }) => {
1148
+ if (!walletClient) {
1149
+ throw new Error("Wallet not connected");
1150
+ }
1151
+ return sdk.token.transfer({ walletClient, to, amount });
1152
+ },
1153
+ onSuccess: () => {
1154
+ queryClient.invalidateQueries({ queryKey: ["djeon402", "balance"] });
1155
+ }
1156
+ });
1157
+ return {
1158
+ transfer: mutation.mutateAsync,
1159
+ isLoading: mutation.isPending,
1160
+ isSuccess: mutation.isSuccess,
1161
+ error: mutation.error,
1162
+ data: mutation.data
1163
+ };
1164
+ }
1165
+
1166
+ // src/react/useX402Receive.ts
1167
+ var import_react_query7 = require("@tanstack/react-query");
1168
+ var import_wagmi3 = require("wagmi");
1169
+ function useX402Receive() {
1170
+ const { sdk } = useDjeon402();
1171
+ const { data: walletClient } = (0, import_wagmi3.useWalletClient)();
1172
+ const mutation = (0, import_react_query7.useMutation)({
1173
+ mutationFn: async (params) => {
1174
+ if (!walletClient) {
1175
+ throw new Error("Wallet not connected");
1176
+ }
1177
+ return sdk.x402.signReceiveWithWallet({
1178
+ walletClient,
1179
+ ...params
1180
+ });
1181
+ }
1182
+ });
1183
+ return {
1184
+ signReceive: mutation.mutateAsync,
1185
+ isLoading: mutation.isPending,
1186
+ isSuccess: mutation.isSuccess,
1187
+ error: mutation.error,
1188
+ authorization: mutation.data
1189
+ };
1190
+ }
1191
+
1192
+ // src/react/useX402Transfer.ts
1193
+ var import_react_query8 = require("@tanstack/react-query");
1194
+ var import_wagmi4 = require("wagmi");
1195
+ function useX402Transfer() {
1196
+ const { sdk } = useDjeon402();
1197
+ const { data: walletClient } = (0, import_wagmi4.useWalletClient)();
1198
+ const mutation = (0, import_react_query8.useMutation)({
1199
+ mutationFn: async (params) => {
1200
+ if (!walletClient) {
1201
+ throw new Error("Wallet not connected");
1202
+ }
1203
+ return sdk.x402.signTransferWithWallet({
1204
+ walletClient,
1205
+ ...params
1206
+ });
1207
+ }
1208
+ });
1209
+ return {
1210
+ signTransfer: mutation.mutateAsync,
1211
+ isLoading: mutation.isPending,
1212
+ isSuccess: mutation.isSuccess,
1213
+ error: mutation.error,
1214
+ authorization: mutation.data
1215
+ };
1216
+ }
1217
+ // Annotate the CommonJS export names for ESM import in node:
1218
+ 0 && (module.exports = {
1219
+ Djeon402Provider,
1220
+ useApprove,
1221
+ useBalance,
1222
+ useDjeon402,
1223
+ useIsBlacklisted,
1224
+ useKYCData,
1225
+ useTokenInfo,
1226
+ useTransfer,
1227
+ useX402Receive,
1228
+ useX402Transfer
1229
+ });
1230
+ //# sourceMappingURL=index.cjs.map