@perkos/contracts-erc8004 1.0.0 → 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.
package/README.md ADDED
@@ -0,0 +1,449 @@
1
+ # @perkos/contracts-erc8004
2
+
3
+ ERC-8004 Decentralized AI Agent Registry contract ABIs and utilities. Provides TypeScript types and ABIs for interacting with ERC-8004 compliant smart contracts.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @perkos/contracts-erc8004
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ ERC-8004 defines three core registries for decentralized AI agent management:
14
+
15
+ - **IdentityRegistry**: NFT-based agent identity with metadata and wallet management
16
+ - **ReputationRegistry**: Client feedback system with filtering by tags and reviewers
17
+ - **ValidationRegistry**: Request-response validation model for third-party attestations
18
+
19
+ ## Usage
20
+
21
+ ### Identity Registry
22
+
23
+ Register and manage agent identities as ERC-721 NFTs.
24
+
25
+ ```typescript
26
+ import { createPublicClient, createWalletClient, http } from 'viem';
27
+ import { base } from 'viem/chains';
28
+ import { IDENTITY_REGISTRY_ABI, type MetadataEntry } from '@perkos/contracts-erc8004';
29
+
30
+ const IDENTITY_REGISTRY = '0x...'; // Contract address
31
+
32
+ const publicClient = createPublicClient({
33
+ chain: base,
34
+ transport: http()
35
+ });
36
+
37
+ // Get agent info
38
+ const tokenURI = await publicClient.readContract({
39
+ address: IDENTITY_REGISTRY,
40
+ abi: IDENTITY_REGISTRY_ABI,
41
+ functionName: 'tokenURI',
42
+ args: [1n] // agentId
43
+ });
44
+
45
+ const owner = await publicClient.readContract({
46
+ address: IDENTITY_REGISTRY,
47
+ abi: IDENTITY_REGISTRY_ABI,
48
+ functionName: 'ownerOf',
49
+ args: [1n]
50
+ });
51
+
52
+ // Get metadata
53
+ const description = await publicClient.readContract({
54
+ address: IDENTITY_REGISTRY,
55
+ abi: IDENTITY_REGISTRY_ABI,
56
+ functionName: 'getMetadata',
57
+ args: [1n, 'description']
58
+ });
59
+
60
+ // Get all agents by owner
61
+ const agentIds = await publicClient.readContract({
62
+ address: IDENTITY_REGISTRY,
63
+ abi: IDENTITY_REGISTRY_ABI,
64
+ functionName: 'getAgentsByOwner',
65
+ args: ['0x...']
66
+ });
67
+
68
+ // Register new agent with metadata
69
+ const metadata: MetadataEntry[] = [
70
+ { key: 'description', value: 'AI Assistant Agent' },
71
+ { key: 'capabilities', value: 'chat,analysis,code' }
72
+ ];
73
+
74
+ const hash = await walletClient.writeContract({
75
+ address: IDENTITY_REGISTRY,
76
+ abi: IDENTITY_REGISTRY_ABI,
77
+ functionName: 'register',
78
+ args: ['ipfs://...', metadata]
79
+ });
80
+ ```
81
+
82
+ ### Reputation Registry
83
+
84
+ Submit and query client feedback for agents.
85
+
86
+ ```typescript
87
+ import { REPUTATION_REGISTRY_ABI, type Feedback, type ReputationSummary } from '@perkos/contracts-erc8004';
88
+
89
+ const REPUTATION_REGISTRY = '0x...';
90
+
91
+ // Get reputation summary
92
+ const [count, averageScore] = await publicClient.readContract({
93
+ address: REPUTATION_REGISTRY,
94
+ abi: REPUTATION_REGISTRY_ABI,
95
+ functionName: 'getSummary',
96
+ args: [
97
+ 1n, // agentId
98
+ [], // clientAddresses (empty = all)
99
+ '', // tag1 filter (empty = all)
100
+ '' // tag2 filter (empty = all)
101
+ ]
102
+ });
103
+
104
+ // Get detailed feedback
105
+ const feedback = await publicClient.readContract({
106
+ address: REPUTATION_REGISTRY,
107
+ abi: REPUTATION_REGISTRY_ABI,
108
+ functionName: 'getFeedbackDetails',
109
+ args: [1n, '0x...', 0n] // agentId, clientAddress, index
110
+ });
111
+
112
+ // Submit feedback (score 0-100)
113
+ const hash = await walletClient.writeContract({
114
+ address: REPUTATION_REGISTRY,
115
+ abi: REPUTATION_REGISTRY_ABI,
116
+ functionName: 'giveFeedback',
117
+ args: [
118
+ 1n, // agentId
119
+ 85, // score (0-100)
120
+ 'quality', // tag1
121
+ 'speed', // tag2
122
+ '/api/chat', // endpoint
123
+ 'ipfs://...', // feedbackURI
124
+ '0x...' // feedbackHash
125
+ ]
126
+ });
127
+
128
+ // Simple feedback (score only)
129
+ const hash = await walletClient.writeContract({
130
+ address: REPUTATION_REGISTRY,
131
+ abi: REPUTATION_REGISTRY_ABI,
132
+ functionName: 'giveFeedback',
133
+ args: [1n, 90] // agentId, score
134
+ });
135
+ ```
136
+
137
+ ### Validation Registry
138
+
139
+ Request and respond to third-party validations.
140
+
141
+ ```typescript
142
+ import {
143
+ VALIDATION_REGISTRY_ABI,
144
+ ValidationStatus,
145
+ isValidationApproved,
146
+ getValidationStatusString,
147
+ type ValidationRequest,
148
+ type ValidationSummary
149
+ } from '@perkos/contracts-erc8004';
150
+
151
+ const VALIDATION_REGISTRY = '0x...';
152
+
153
+ // Request validation
154
+ const requestHash = await walletClient.writeContract({
155
+ address: VALIDATION_REGISTRY,
156
+ abi: VALIDATION_REGISTRY_ABI,
157
+ functionName: 'validationRequest',
158
+ args: [
159
+ '0x...', // validatorAddress
160
+ 1n, // agentId
161
+ 'ipfs://...', // requestURI
162
+ '0x...' // requestDataHash
163
+ ]
164
+ });
165
+
166
+ // Get validation status
167
+ const [status, agentId, validator, response, tag] = await publicClient.readContract({
168
+ address: VALIDATION_REGISTRY,
169
+ abi: VALIDATION_REGISTRY_ABI,
170
+ functionName: 'getValidationStatus',
171
+ args: [requestHash]
172
+ });
173
+
174
+ // Check if approved
175
+ if (isValidationApproved(status)) {
176
+ console.log('Validation approved!');
177
+ }
178
+
179
+ // Get status string
180
+ console.log(getValidationStatusString(status)); // 'approved' | 'pending' | 'rejected' | etc.
181
+
182
+ // Get validation statistics
183
+ const summary = await publicClient.readContract({
184
+ address: VALIDATION_REGISTRY,
185
+ abi: VALIDATION_REGISTRY_ABI,
186
+ functionName: 'getValidationStatistics',
187
+ args: [1n]
188
+ });
189
+
190
+ // Check for specific validation type
191
+ const hasSecurityAudit = await publicClient.readContract({
192
+ address: VALIDATION_REGISTRY,
193
+ abi: VALIDATION_REGISTRY_ABI,
194
+ functionName: 'hasApprovedValidation',
195
+ args: [1n, 'security']
196
+ });
197
+
198
+ // Respond to validation (validator only)
199
+ await walletClient.writeContract({
200
+ address: VALIDATION_REGISTRY,
201
+ abi: VALIDATION_REGISTRY_ABI,
202
+ functionName: 'validationResponse',
203
+ args: [
204
+ requestHash, // requestHash
205
+ 85, // response (0-100)
206
+ 'ipfs://...', // responseURI
207
+ '0x...', // responseDataHash
208
+ 'security' // tag
209
+ ]
210
+ });
211
+ ```
212
+
213
+ ## API Reference
214
+
215
+ ### ABIs
216
+
217
+ ```typescript
218
+ import {
219
+ IDENTITY_REGISTRY_ABI,
220
+ REPUTATION_REGISTRY_ABI,
221
+ VALIDATION_REGISTRY_ABI,
222
+ ERC8004_ABIS
223
+ } from '@perkos/contracts-erc8004';
224
+
225
+ // Combined ABIs object
226
+ const { IdentityRegistry, ReputationRegistry, ValidationRegistry } = ERC8004_ABIS;
227
+ ```
228
+
229
+ ### Types
230
+
231
+ ```typescript
232
+ import type {
233
+ Hex,
234
+ MetadataEntry,
235
+ Feedback,
236
+ ReputationSummary,
237
+ ValidationStatus,
238
+ ValidationRequest,
239
+ ValidationSummary
240
+ } from '@perkos/contracts-erc8004';
241
+ ```
242
+
243
+ #### MetadataEntry
244
+
245
+ ```typescript
246
+ interface MetadataEntry {
247
+ key: string;
248
+ value: string;
249
+ }
250
+ ```
251
+
252
+ #### Feedback
253
+
254
+ ```typescript
255
+ interface Feedback {
256
+ client: Address;
257
+ score: number; // 0-100
258
+ tag1: string;
259
+ tag2: string;
260
+ endpoint: string;
261
+ feedbackURI: string;
262
+ feedbackHash: Hex;
263
+ timestamp: bigint;
264
+ isRevoked: boolean;
265
+ responseURI: string;
266
+ responseHash: Hex;
267
+ }
268
+ ```
269
+
270
+ #### ReputationSummary
271
+
272
+ ```typescript
273
+ interface ReputationSummary {
274
+ count: bigint;
275
+ averageScore: number; // 0-100
276
+ }
277
+ ```
278
+
279
+ #### ValidationStatus
280
+
281
+ ```typescript
282
+ enum ValidationStatus {
283
+ None = 0,
284
+ Pending = 1,
285
+ Approved = 2,
286
+ Rejected = 3,
287
+ Cancelled = 4
288
+ }
289
+ ```
290
+
291
+ #### ValidationRequest
292
+
293
+ ```typescript
294
+ interface ValidationRequest {
295
+ agentId: bigint;
296
+ requester: Address;
297
+ validatorAddress: Address;
298
+ requestURI: string;
299
+ requestDataHash: Hex;
300
+ requestedAt: bigint;
301
+ status: ValidationStatus;
302
+ response: number; // 0-100
303
+ responseURI: string;
304
+ responseDataHash: Hex;
305
+ tag: string;
306
+ respondedAt: bigint;
307
+ }
308
+ ```
309
+
310
+ #### ValidationSummary
311
+
312
+ ```typescript
313
+ interface ValidationSummary {
314
+ totalRequests: bigint;
315
+ approvedCount: bigint;
316
+ rejectedCount: bigint;
317
+ pendingCount: bigint;
318
+ averageResponse: number; // 0-100
319
+ }
320
+ ```
321
+
322
+ ### Constants
323
+
324
+ #### VALIDATION_TAGS
325
+
326
+ ```typescript
327
+ import { VALIDATION_TAGS } from '@perkos/contracts-erc8004';
328
+
329
+ // Pre-defined validation tags per EIP-8004
330
+ VALIDATION_TAGS.SECURITY // 'security'
331
+ VALIDATION_TAGS.COMPLIANCE // 'compliance'
332
+ VALIDATION_TAGS.PERFORMANCE // 'performance'
333
+ VALIDATION_TAGS.IDENTITY // 'identity'
334
+ VALIDATION_TAGS.CAPABILITY // 'capability'
335
+ VALIDATION_TAGS.KYC // 'kyc'
336
+ VALIDATION_TAGS.AML // 'aml'
337
+ ```
338
+
339
+ #### FEEDBACK_TAGS
340
+
341
+ ```typescript
342
+ import { FEEDBACK_TAGS } from '@perkos/contracts-erc8004';
343
+
344
+ // Pre-defined feedback tags per EIP-8004
345
+ FEEDBACK_TAGS.QUALITY // 'quality'
346
+ FEEDBACK_TAGS.SPEED // 'speed'
347
+ FEEDBACK_TAGS.RELIABILITY // 'reliability'
348
+ FEEDBACK_TAGS.ACCURACY // 'accuracy'
349
+ FEEDBACK_TAGS.SUPPORT // 'support'
350
+ ```
351
+
352
+ ### Utility Functions
353
+
354
+ ```typescript
355
+ import {
356
+ isValidationApproved,
357
+ getValidationStatusString,
358
+ getScorePercentage,
359
+ isScoreApproved
360
+ } from '@perkos/contracts-erc8004';
361
+
362
+ // Check if validation is approved
363
+ isValidationApproved(ValidationStatus.Approved); // true
364
+
365
+ // Get human-readable status
366
+ getValidationStatusString(ValidationStatus.Pending); // 'pending'
367
+
368
+ // Normalize score to 0-100 range
369
+ getScorePercentage(85); // 85
370
+
371
+ // Check if score indicates approval (>50)
372
+ isScoreApproved(85); // true
373
+ isScoreApproved(30); // false
374
+ ```
375
+
376
+ ## Contract Functions
377
+
378
+ ### Identity Registry
379
+
380
+ | Function | Description |
381
+ |----------|-------------|
382
+ | `register(agentURI, metadata?)` | Register new agent identity |
383
+ | `setAgentURI(agentId, newURI)` | Update agent URI |
384
+ | `setMetadata(agentId, key, value)` | Set metadata entry |
385
+ | `setAgentWallet(agentId, newWallet, deadline, signature)` | Update agent wallet |
386
+ | `tokenURI(agentId)` | Get agent URI |
387
+ | `ownerOf(agentId)` | Get agent owner |
388
+ | `getMetadata(agentId, key)` | Get metadata value |
389
+ | `getAgentWallet(agentId)` | Get agent wallet address |
390
+ | `getAgentsByOwner(owner)` | Get all agents owned by address |
391
+ | `totalAgents()` | Get total registered agents |
392
+
393
+ ### Reputation Registry
394
+
395
+ | Function | Description |
396
+ |----------|-------------|
397
+ | `giveFeedback(agentId, score, ...)` | Submit feedback |
398
+ | `revokeFeedback(agentId, index)` | Revoke feedback |
399
+ | `appendResponse(agentId, client, index, responseURI, hash)` | Add agent response |
400
+ | `getSummary(agentId, clients, tag1, tag2)` | Get reputation summary |
401
+ | `readFeedback(agentId, client, index)` | Read specific feedback |
402
+ | `readAllFeedback(agentId, clients, tag1, tag2, includeRevoked)` | Read all feedback |
403
+ | `getFeedbackDetails(agentId, client, index)` | Get full feedback details |
404
+ | `getClients(agentId)` | Get all feedback clients |
405
+
406
+ ### Validation Registry
407
+
408
+ | Function | Description |
409
+ |----------|-------------|
410
+ | `validationRequest(validator, agentId, requestURI, hash)` | Request validation |
411
+ | `validationResponse(requestHash, response, responseURI, hash, tag)` | Submit response |
412
+ | `cancelValidation(requestHash)` | Cancel validation request |
413
+ | `getValidationStatus(requestHash)` | Get validation status |
414
+ | `getValidation(requestHash)` | Get full validation details |
415
+ | `getSummary(agentId, validators, tag)` | Get validation summary |
416
+ | `hasApprovedValidation(agentId, tag)` | Check for approved validation |
417
+ | `getValidationStatistics(agentId)` | Get agent validation stats |
418
+ | `getAgentValidations(agentId)` | Get all validation hashes |
419
+ | `getPendingRequests(validator)` | Get pending requests for validator |
420
+
421
+ ## Events
422
+
423
+ ### Identity Registry Events
424
+
425
+ - `Registered(agentId, agentURI, owner)`
426
+ - `URIUpdated(agentId, newURI, updatedBy)`
427
+ - `MetadataSet(agentId, indexedKey, metadataKey, metadataValue)`
428
+ - `AgentWalletUpdated(agentId, oldWallet, newWallet)`
429
+
430
+ ### Reputation Registry Events
431
+
432
+ - `NewFeedback(agentId, clientAddress, score, tag1, tag2, endpoint, feedbackURI, feedbackHash)`
433
+ - `FeedbackRevoked(agentId, clientAddress, feedbackIndex)`
434
+ - `ResponseAppended(agentId, clientAddress, feedbackIndex, responder, responseURI)`
435
+
436
+ ### Validation Registry Events
437
+
438
+ - `ValidationRequested(requestHash, agentId, validatorAddress, requestURI, requestDataHash)`
439
+ - `ValidationResponseSubmitted(requestHash, agentId, validatorAddress, response, tag)`
440
+ - `ValidationCancelled(requestHash, agentId, cancelledBy)`
441
+
442
+ ## Related Packages
443
+
444
+ - [@perkos/types-x402](https://www.npmjs.com/package/@perkos/types-x402) - Core x402 types
445
+ - [@perkos/service-x402](https://www.npmjs.com/package/@perkos/service-x402) - x402 service orchestrator
446
+
447
+ ## License
448
+
449
+ MIT