@t402/erc8004 2.7.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,647 @@
1
+ // src/constants.ts
2
+ var IDENTITY_REGISTRIES = {};
3
+ var REPUTATION_REGISTRIES = {};
4
+ var VALIDATION_REGISTRIES = {};
5
+ var ERC8004_EXTENSION_KEY = "erc8004";
6
+ var FEEDBACK_TAGS = {
7
+ /** tag1: Payment completed successfully */
8
+ PAYMENT_SUCCESS: "paymentSuccess",
9
+ /** tag1: Payment verification failed */
10
+ PAYMENT_FAILED: "paymentFailed",
11
+ /** tag1: Service quality rating */
12
+ SERVICE_QUALITY: "starred",
13
+ /** tag2: Response time measurement */
14
+ RESPONSE_TIME: "responseTime",
15
+ /** tag2: Uptime measurement */
16
+ UPTIME: "uptime"
17
+ };
18
+ var IDENTITY_REGISTRY_DOMAIN = {
19
+ name: "IdentityRegistry",
20
+ version: "1"
21
+ };
22
+ var SET_AGENT_WALLET_TYPES = {
23
+ SetAgentWallet: [
24
+ { name: "agentId", type: "uint256" },
25
+ { name: "newWallet", type: "address" },
26
+ { name: "deadline", type: "uint256" },
27
+ { name: "nonce", type: "uint256" }
28
+ ]
29
+ };
30
+
31
+ // src/abis.ts
32
+ var identityRegistryAbi = [
33
+ {
34
+ type: "function",
35
+ name: "register",
36
+ inputs: [
37
+ { name: "agentURI", type: "string" },
38
+ {
39
+ name: "metadata",
40
+ type: "tuple[]",
41
+ components: [
42
+ { name: "metadataKey", type: "string" },
43
+ { name: "metadataValue", type: "bytes" }
44
+ ]
45
+ }
46
+ ],
47
+ outputs: [{ type: "uint256" }],
48
+ stateMutability: "nonpayable"
49
+ },
50
+ {
51
+ type: "function",
52
+ name: "getAgentWallet",
53
+ inputs: [{ name: "agentId", type: "uint256" }],
54
+ outputs: [{ type: "address" }],
55
+ stateMutability: "view"
56
+ },
57
+ {
58
+ type: "function",
59
+ name: "tokenURI",
60
+ inputs: [{ name: "tokenId", type: "uint256" }],
61
+ outputs: [{ type: "string" }],
62
+ stateMutability: "view"
63
+ },
64
+ {
65
+ type: "function",
66
+ name: "ownerOf",
67
+ inputs: [{ name: "tokenId", type: "uint256" }],
68
+ outputs: [{ type: "address" }],
69
+ stateMutability: "view"
70
+ },
71
+ {
72
+ type: "function",
73
+ name: "getMetadata",
74
+ inputs: [
75
+ { name: "agentId", type: "uint256" },
76
+ { name: "metadataKey", type: "string" }
77
+ ],
78
+ outputs: [{ type: "bytes" }],
79
+ stateMutability: "view"
80
+ },
81
+ {
82
+ type: "function",
83
+ name: "setAgentWallet",
84
+ inputs: [
85
+ { name: "agentId", type: "uint256" },
86
+ { name: "newWallet", type: "address" },
87
+ { name: "deadline", type: "uint256" },
88
+ { name: "signature", type: "bytes" }
89
+ ],
90
+ outputs: [],
91
+ stateMutability: "nonpayable"
92
+ },
93
+ {
94
+ type: "event",
95
+ name: "Registered",
96
+ inputs: [
97
+ { name: "agentId", type: "uint256", indexed: true },
98
+ { name: "agentURI", type: "string", indexed: false },
99
+ { name: "owner", type: "address", indexed: true }
100
+ ]
101
+ }
102
+ ];
103
+ var reputationRegistryAbi = [
104
+ {
105
+ type: "function",
106
+ name: "giveFeedback",
107
+ inputs: [
108
+ { name: "agentId", type: "uint256" },
109
+ { name: "value", type: "int128" },
110
+ { name: "valueDecimals", type: "uint8" },
111
+ { name: "tag1", type: "string" },
112
+ { name: "tag2", type: "string" },
113
+ { name: "endpoint", type: "string" },
114
+ { name: "feedbackURI", type: "string" },
115
+ { name: "feedbackHash", type: "bytes32" }
116
+ ],
117
+ outputs: [],
118
+ stateMutability: "nonpayable"
119
+ },
120
+ {
121
+ type: "function",
122
+ name: "getSummary",
123
+ inputs: [
124
+ { name: "agentId", type: "uint256" },
125
+ { name: "clientAddresses", type: "address[]" },
126
+ { name: "tag1", type: "string" },
127
+ { name: "tag2", type: "string" }
128
+ ],
129
+ outputs: [
130
+ { name: "count", type: "uint64" },
131
+ { name: "summaryValue", type: "int128" },
132
+ { name: "summaryValueDecimals", type: "uint8" }
133
+ ],
134
+ stateMutability: "view"
135
+ },
136
+ {
137
+ type: "function",
138
+ name: "revokeFeedback",
139
+ inputs: [
140
+ { name: "agentId", type: "uint256" },
141
+ { name: "feedbackIndex", type: "uint64" }
142
+ ],
143
+ outputs: [],
144
+ stateMutability: "nonpayable"
145
+ },
146
+ {
147
+ type: "function",
148
+ name: "getClients",
149
+ inputs: [{ name: "agentId", type: "uint256" }],
150
+ outputs: [{ type: "address[]" }],
151
+ stateMutability: "view"
152
+ },
153
+ {
154
+ type: "event",
155
+ name: "NewFeedback",
156
+ inputs: [
157
+ { name: "agentId", type: "uint256", indexed: true },
158
+ { name: "clientAddress", type: "address", indexed: true },
159
+ { name: "feedbackIndex", type: "uint64", indexed: false },
160
+ { name: "value", type: "int128", indexed: false },
161
+ { name: "valueDecimals", type: "uint8", indexed: false },
162
+ { name: "indexedTag1", type: "string", indexed: true },
163
+ { name: "tag1", type: "string", indexed: false },
164
+ { name: "tag2", type: "string", indexed: false },
165
+ { name: "endpoint", type: "string", indexed: false },
166
+ { name: "feedbackURI", type: "string", indexed: false },
167
+ { name: "feedbackHash", type: "bytes32", indexed: false }
168
+ ]
169
+ }
170
+ ];
171
+ var validationRegistryAbi = [
172
+ {
173
+ type: "function",
174
+ name: "validationRequest",
175
+ inputs: [
176
+ { name: "validatorAddress", type: "address" },
177
+ { name: "agentId", type: "uint256" },
178
+ { name: "requestURI", type: "string" },
179
+ { name: "requestHash", type: "bytes32" }
180
+ ],
181
+ outputs: [],
182
+ stateMutability: "nonpayable"
183
+ },
184
+ {
185
+ type: "function",
186
+ name: "validationResponse",
187
+ inputs: [
188
+ { name: "requestHash", type: "bytes32" },
189
+ { name: "response", type: "uint8" },
190
+ { name: "responseURI", type: "string" },
191
+ { name: "responseHash", type: "bytes32" },
192
+ { name: "tag", type: "string" }
193
+ ],
194
+ outputs: [],
195
+ stateMutability: "nonpayable"
196
+ },
197
+ {
198
+ type: "function",
199
+ name: "getValidationStatus",
200
+ inputs: [{ name: "requestHash", type: "bytes32" }],
201
+ outputs: [
202
+ { name: "validatorAddress", type: "address" },
203
+ { name: "agentId", type: "uint256" },
204
+ { name: "response", type: "uint8" },
205
+ { name: "responseHash", type: "bytes32" },
206
+ { name: "tag", type: "string" },
207
+ { name: "lastUpdate", type: "uint256" }
208
+ ],
209
+ stateMutability: "view"
210
+ },
211
+ {
212
+ type: "function",
213
+ name: "getSummary",
214
+ inputs: [
215
+ { name: "agentId", type: "uint256" },
216
+ { name: "validatorAddresses", type: "address[]" },
217
+ { name: "tag", type: "string" }
218
+ ],
219
+ outputs: [
220
+ { name: "count", type: "uint64" },
221
+ { name: "averageResponse", type: "uint8" }
222
+ ],
223
+ stateMutability: "view"
224
+ },
225
+ {
226
+ type: "event",
227
+ name: "ValidationRequest",
228
+ inputs: [
229
+ { name: "validatorAddress", type: "address", indexed: true },
230
+ { name: "agentId", type: "uint256", indexed: true },
231
+ { name: "requestURI", type: "string", indexed: false },
232
+ { name: "requestHash", type: "bytes32", indexed: true }
233
+ ]
234
+ },
235
+ {
236
+ type: "event",
237
+ name: "ValidationResponse",
238
+ inputs: [
239
+ { name: "validatorAddress", type: "address", indexed: true },
240
+ { name: "agentId", type: "uint256", indexed: true },
241
+ { name: "requestHash", type: "bytes32", indexed: true },
242
+ { name: "response", type: "uint8", indexed: false },
243
+ { name: "responseURI", type: "string", indexed: false },
244
+ { name: "responseHash", type: "bytes32", indexed: false },
245
+ { name: "tag", type: "string", indexed: false }
246
+ ]
247
+ }
248
+ ];
249
+
250
+ // src/identity.ts
251
+ function parseAgentRegistry(registryId) {
252
+ const parts = registryId.split(":");
253
+ if (parts.length < 3) {
254
+ throw new Error(
255
+ `Invalid agent registry ID: ${registryId}. Expected format: namespace:chainId:address`
256
+ );
257
+ }
258
+ const namespace = parts[0];
259
+ const chainId = parts[1];
260
+ const address = parts.slice(2).join(":");
261
+ if (!namespace || !chainId || !address) {
262
+ throw new Error(
263
+ `Invalid agent registry ID: ${registryId}. All parts must be non-empty`
264
+ );
265
+ }
266
+ return { namespace, chainId, address, id: registryId };
267
+ }
268
+ async function getAgentIdentity(client, identityRegistry, agentId, registryId) {
269
+ const [agentWallet, owner, agentURI] = await Promise.all([
270
+ client.readContract({
271
+ address: identityRegistry,
272
+ abi: identityRegistryAbi,
273
+ functionName: "getAgentWallet",
274
+ args: [agentId]
275
+ }),
276
+ client.readContract({
277
+ address: identityRegistry,
278
+ abi: identityRegistryAbi,
279
+ functionName: "ownerOf",
280
+ args: [agentId]
281
+ }),
282
+ client.readContract({
283
+ address: identityRegistry,
284
+ abi: identityRegistryAbi,
285
+ functionName: "tokenURI",
286
+ args: [agentId]
287
+ })
288
+ ]);
289
+ return {
290
+ agentId,
291
+ owner,
292
+ agentURI,
293
+ agentWallet,
294
+ registry: parseAgentRegistry(registryId)
295
+ };
296
+ }
297
+ async function fetchRegistrationFile(agentURI) {
298
+ const response = await fetch(agentURI);
299
+ if (!response.ok) {
300
+ throw new Error(
301
+ `Failed to fetch registration file from ${agentURI}: ${response.status}`
302
+ );
303
+ }
304
+ return response.json();
305
+ }
306
+ async function resolveAgent(client, identityRegistry, agentId, registryId) {
307
+ const identity = await getAgentIdentity(
308
+ client,
309
+ identityRegistry,
310
+ agentId,
311
+ registryId
312
+ );
313
+ const registration = await fetchRegistrationFile(identity.agentURI);
314
+ return { ...identity, registration };
315
+ }
316
+ async function verifyPayToMatchesAgent(client, identityRegistry, agentId, payTo) {
317
+ const agentWallet = await client.readContract({
318
+ address: identityRegistry,
319
+ abi: identityRegistryAbi,
320
+ functionName: "getAgentWallet",
321
+ args: [agentId]
322
+ });
323
+ return agentWallet.toLowerCase() === payTo.toLowerCase();
324
+ }
325
+
326
+ // src/reputation.ts
327
+ async function getReputationSummary(client, reputationRegistry, agentId, trustedReviewers, tag1 = "", tag2 = "") {
328
+ const result = await client.readContract({
329
+ address: reputationRegistry,
330
+ abi: reputationRegistryAbi,
331
+ functionName: "getSummary",
332
+ args: [agentId, trustedReviewers, tag1, tag2]
333
+ });
334
+ const [count, summaryValue, summaryValueDecimals] = result;
335
+ const divisor = 10 ** summaryValueDecimals;
336
+ const normalizedScore = count > 0n ? Math.min(100, Math.max(0, Number(summaryValue) / divisor)) : 0;
337
+ return {
338
+ agentId,
339
+ count,
340
+ summaryValue,
341
+ summaryValueDecimals,
342
+ normalizedScore
343
+ };
344
+ }
345
+ function buildFeedbackFile(agentId, agentRegistry, clientAddress, value, valueDecimals, tag1, tag2, proofOfPayment) {
346
+ return {
347
+ agentRegistry,
348
+ agentId,
349
+ clientAddress,
350
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
351
+ value,
352
+ valueDecimals,
353
+ tag1,
354
+ tag2,
355
+ ...proofOfPayment && { proofOfPayment }
356
+ };
357
+ }
358
+ async function submitFeedback(client, reputationRegistry, params) {
359
+ return client.writeContract({
360
+ address: reputationRegistry,
361
+ abi: reputationRegistryAbi,
362
+ functionName: "giveFeedback",
363
+ args: [
364
+ params.agentId,
365
+ params.value,
366
+ params.valueDecimals,
367
+ params.tag1,
368
+ params.tag2,
369
+ params.endpoint ?? "",
370
+ params.feedbackURI ?? "",
371
+ params.feedbackHash ?? "0x" + "0".repeat(64)
372
+ ]
373
+ });
374
+ }
375
+
376
+ // src/validation.ts
377
+ async function submitValidationRequest(client, validationRegistry, params) {
378
+ return client.writeContract({
379
+ address: validationRegistry,
380
+ abi: validationRegistryAbi,
381
+ functionName: "validationRequest",
382
+ args: [
383
+ params.validatorAddress,
384
+ params.agentId,
385
+ params.requestURI,
386
+ params.requestHash
387
+ ]
388
+ });
389
+ }
390
+ async function getValidationStatus(client, validationRegistry, requestHash) {
391
+ const result = await client.readContract({
392
+ address: validationRegistry,
393
+ abi: validationRegistryAbi,
394
+ functionName: "getValidationStatus",
395
+ args: [requestHash]
396
+ });
397
+ return {
398
+ validatorAddress: result[0],
399
+ agentId: result[1],
400
+ response: result[2],
401
+ responseHash: result[3],
402
+ tag: result[4],
403
+ lastUpdate: result[5]
404
+ };
405
+ }
406
+ async function getValidationSummary(client, validationRegistry, agentId, validatorAddresses, tag = "") {
407
+ const result = await client.readContract({
408
+ address: validationRegistry,
409
+ abi: validationRegistryAbi,
410
+ functionName: "getSummary",
411
+ args: [agentId, validatorAddresses, tag]
412
+ });
413
+ return {
414
+ count: result[0],
415
+ averageResponse: result[1]
416
+ };
417
+ }
418
+
419
+ // src/extension.ts
420
+ function declareERC8004Extension(agentId, agentRegistry, agentWallet) {
421
+ return {
422
+ agentId,
423
+ agentRegistry,
424
+ ...agentWallet && { agentWallet }
425
+ };
426
+ }
427
+ function getERC8004Extension(paymentRequired) {
428
+ return paymentRequired.extensions?.[ERC8004_EXTENSION_KEY];
429
+ }
430
+ function createERC8004PayloadExtension(agentId, agentRegistry, verified) {
431
+ return {
432
+ identityVerified: verified,
433
+ agentId,
434
+ agentRegistry
435
+ };
436
+ }
437
+ async function verifyAgentIdentity(client, paymentRequired) {
438
+ const ext = getERC8004Extension(paymentRequired);
439
+ if (!ext) return false;
440
+ const registry = ext.agentRegistry.split(":");
441
+ const registryAddress = registry.slice(2).join(":");
442
+ for (const accept of paymentRequired.accepts) {
443
+ const matches = await verifyPayToMatchesAgent(
444
+ client,
445
+ registryAddress,
446
+ BigInt(ext.agentId),
447
+ accept.payTo
448
+ );
449
+ if (!matches) return false;
450
+ }
451
+ return true;
452
+ }
453
+ function erc8004ResourceServerExtension(config) {
454
+ return {
455
+ key: ERC8004_EXTENSION_KEY,
456
+ enrichDeclaration: async (declaration) => {
457
+ let enriched = declaration;
458
+ if (config.reputationRegistry && config.trustedReviewers?.length) {
459
+ const summary = await getReputationSummary(
460
+ config.client,
461
+ config.reputationRegistry,
462
+ BigInt(enriched.agentId),
463
+ config.trustedReviewers
464
+ );
465
+ enriched = {
466
+ ...enriched,
467
+ reputationScore: summary.normalizedScore,
468
+ feedbackCount: Number(summary.count)
469
+ };
470
+ }
471
+ if (config.validationRegistry && config.trustedValidators?.length) {
472
+ const summary = await getValidationSummary(
473
+ config.client,
474
+ config.validationRegistry,
475
+ BigInt(enriched.agentId),
476
+ config.trustedValidators
477
+ );
478
+ enriched = {
479
+ ...enriched,
480
+ validationScore: summary.averageResponse
481
+ };
482
+ }
483
+ return enriched;
484
+ }
485
+ };
486
+ }
487
+
488
+ // src/hooks.ts
489
+ import { getPaymentRequired } from "@t402/core/types";
490
+ function erc8004IdentityCheck(client, options = {}) {
491
+ const { abortOnFailure = true, abortOnMissing = false } = options;
492
+ return async (context) => {
493
+ const ext = getERC8004Extension(context.paymentRequired);
494
+ if (!ext) {
495
+ if (abortOnMissing) {
496
+ return {
497
+ abort: true,
498
+ reason: "ERC-8004 extension not present in payment requirements"
499
+ };
500
+ }
501
+ return;
502
+ }
503
+ const verified = await verifyAgentIdentity(
504
+ client,
505
+ context.paymentRequired
506
+ );
507
+ if (!verified && abortOnFailure) {
508
+ return {
509
+ abort: true,
510
+ reason: `ERC-8004 identity verification failed for agent ${ext.agentId} on registry ${ext.agentRegistry}`
511
+ };
512
+ }
513
+ };
514
+ }
515
+ async function verifyAgentIdentityFromTask(client, task) {
516
+ const paymentRequired = getPaymentRequired(task);
517
+ if (!paymentRequired) return false;
518
+ return verifyAgentIdentity(client, paymentRequired);
519
+ }
520
+ function getPayloadExtension(context) {
521
+ return context.paymentPayload.extensions?.[ERC8004_EXTENSION_KEY];
522
+ }
523
+ function erc8004ReputationCheck(client, reputationRegistry, config) {
524
+ return async (context) => {
525
+ const ext = getPayloadExtension(context);
526
+ if (!ext) return;
527
+ const summary = await getReputationSummary(
528
+ client,
529
+ reputationRegistry,
530
+ BigInt(ext.agentId),
531
+ config.trustedReviewers,
532
+ config.tag1 ?? "",
533
+ config.tag2 ?? ""
534
+ );
535
+ if (summary.normalizedScore < config.minScore) {
536
+ const action = config.onBelowThreshold ?? "reject";
537
+ if (action === "reject") {
538
+ return {
539
+ abort: true,
540
+ reason: `Agent ${ext.agentId} reputation score ${summary.normalizedScore} is below minimum ${config.minScore}`
541
+ };
542
+ }
543
+ console.warn(
544
+ `[erc8004] Agent ${ext.agentId} reputation score ${summary.normalizedScore} is below minimum ${config.minScore}`
545
+ );
546
+ }
547
+ };
548
+ }
549
+ function erc8004ServerIdentityCheck(client) {
550
+ return async (context) => {
551
+ const ext = getPayloadExtension(context);
552
+ if (!ext) return;
553
+ const registry = ext.agentRegistry.split(":");
554
+ const registryAddress = registry.slice(2).join(":");
555
+ const matches = await verifyPayToMatchesAgent(
556
+ client,
557
+ registryAddress,
558
+ BigInt(ext.agentId),
559
+ context.requirements.payTo
560
+ );
561
+ if (!matches) {
562
+ return {
563
+ abort: true,
564
+ reason: `payTo address ${context.requirements.payTo} does not match on-chain agentWallet for agent ${ext.agentId}`
565
+ };
566
+ }
567
+ };
568
+ }
569
+ function erc8004SubmitFeedback(writeClient, reputationRegistry, config = {}) {
570
+ return async (context) => {
571
+ const ext = getPayloadExtension(context);
572
+ if (!ext) return;
573
+ if (!context.result.success) return;
574
+ const tag1 = config.tag1 ?? FEEDBACK_TAGS.PAYMENT_SUCCESS;
575
+ const tag2 = config.tag2 ?? "";
576
+ let feedbackURI = "";
577
+ const feedbackHash = "0x" + "0".repeat(64);
578
+ if (config.includeProofOfPayment && context.result.transaction) {
579
+ buildFeedbackFile(
580
+ ext.agentId,
581
+ ext.agentRegistry,
582
+ context.result.payer ?? "",
583
+ 100,
584
+ 0,
585
+ tag1,
586
+ tag2,
587
+ {
588
+ fromAddress: context.result.payer ?? "",
589
+ toAddress: context.requirements.payTo,
590
+ chainId: context.requirements.network,
591
+ txHash: context.result.transaction
592
+ }
593
+ );
594
+ if (config.feedbackBaseURI) {
595
+ feedbackURI = `${config.feedbackBaseURI}/${context.result.transaction}.json`;
596
+ }
597
+ }
598
+ submitFeedback(writeClient, reputationRegistry, {
599
+ agentId: BigInt(ext.agentId),
600
+ value: 100n,
601
+ valueDecimals: 0,
602
+ tag1,
603
+ tag2,
604
+ endpoint: context.paymentPayload.resource?.url,
605
+ feedbackURI,
606
+ feedbackHash
607
+ }).catch((err) => {
608
+ console.warn(
609
+ `[erc8004] Failed to submit feedback for agent ${ext.agentId}:`,
610
+ err
611
+ );
612
+ });
613
+ };
614
+ }
615
+ export {
616
+ ERC8004_EXTENSION_KEY,
617
+ FEEDBACK_TAGS,
618
+ IDENTITY_REGISTRIES,
619
+ IDENTITY_REGISTRY_DOMAIN,
620
+ REPUTATION_REGISTRIES,
621
+ SET_AGENT_WALLET_TYPES,
622
+ VALIDATION_REGISTRIES,
623
+ buildFeedbackFile,
624
+ createERC8004PayloadExtension,
625
+ declareERC8004Extension,
626
+ erc8004IdentityCheck,
627
+ erc8004ReputationCheck,
628
+ erc8004ResourceServerExtension,
629
+ erc8004ServerIdentityCheck,
630
+ erc8004SubmitFeedback,
631
+ fetchRegistrationFile,
632
+ getAgentIdentity,
633
+ getERC8004Extension,
634
+ getReputationSummary,
635
+ getValidationStatus,
636
+ getValidationSummary,
637
+ identityRegistryAbi,
638
+ parseAgentRegistry,
639
+ reputationRegistryAbi,
640
+ resolveAgent,
641
+ submitFeedback,
642
+ submitValidationRequest,
643
+ validationRegistryAbi,
644
+ verifyAgentIdentity,
645
+ verifyAgentIdentityFromTask,
646
+ verifyPayToMatchesAgent
647
+ };
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@t402/erc8004",
3
+ "version": "2.7.0",
4
+ "description": "ERC-8004 Trustless Agents integration for t402 payment protocol",
5
+ "main": "./dist/cjs/index.cjs",
6
+ "module": "./dist/esm/index.mjs",
7
+ "types": "./dist/esm/index.d.mts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/esm/index.d.mts",
12
+ "default": "./dist/esm/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/cjs/index.d.cts",
16
+ "default": "./dist/cjs/index.cjs"
17
+ }
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "dependencies": {
25
+ "@t402/core": "2.7.0"
26
+ },
27
+ "peerDependencies": {
28
+ "viem": "^2.0.0"
29
+ },
30
+ "peerDependenciesMeta": {
31
+ "viem": {
32
+ "optional": true
33
+ }
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^25.2.3",
37
+ "@vitest/coverage-v8": "^3.2.4",
38
+ "tsup": "^8.5.1",
39
+ "typescript": "^5.9.3",
40
+ "vite-tsconfig-paths": "^6.1.1",
41
+ "vitest": "^3.2.4"
42
+ },
43
+ "keywords": [
44
+ "t402",
45
+ "erc8004",
46
+ "trustless-agents",
47
+ "agent-identity",
48
+ "reputation",
49
+ "payments",
50
+ "crypto"
51
+ ],
52
+ "author": "T402 Contributors",
53
+ "license": "Apache-2.0",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "https://github.com/t402-io/t402.git",
57
+ "directory": "sdks/typescript/packages/erc8004"
58
+ },
59
+ "bugs": {
60
+ "url": "https://github.com/t402-io/t402/issues"
61
+ },
62
+ "homepage": "https://t402.io",
63
+ "publishConfig": {
64
+ "access": "public"
65
+ },
66
+ "scripts": {
67
+ "build": "tsup",
68
+ "test": "vitest run",
69
+ "test:watch": "vitest",
70
+ "typecheck": "tsc --noEmit",
71
+ "clean": "rm -rf dist coverage"
72
+ }
73
+ }