8004-solana 0.2.2 → 0.4.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.
Files changed (118) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +105 -25
  3. package/dist/core/agent-mint-resolver.d.ts +53 -29
  4. package/dist/core/agent-mint-resolver.d.ts.map +1 -1
  5. package/dist/core/agent-mint-resolver.js +117 -72
  6. package/dist/core/agent-mint-resolver.js.map +1 -1
  7. package/dist/core/atom-pda.d.ts +34 -0
  8. package/dist/core/atom-pda.d.ts.map +1 -0
  9. package/dist/core/atom-pda.js +45 -0
  10. package/dist/core/atom-pda.js.map +1 -0
  11. package/dist/core/atom-schemas.d.ts +221 -0
  12. package/dist/core/atom-schemas.d.ts.map +1 -0
  13. package/dist/core/atom-schemas.js +393 -0
  14. package/dist/core/atom-schemas.js.map +1 -0
  15. package/dist/core/borsh-schemas.d.ts +112 -186
  16. package/dist/core/borsh-schemas.d.ts.map +1 -1
  17. package/dist/core/borsh-schemas.js +502 -426
  18. package/dist/core/borsh-schemas.js.map +1 -1
  19. package/dist/core/client.d.ts.map +1 -1
  20. package/dist/core/client.js +11 -4
  21. package/dist/core/client.js.map +1 -1
  22. package/dist/core/config-reader.d.ts +36 -6
  23. package/dist/core/config-reader.d.ts.map +1 -1
  24. package/dist/core/config-reader.js +83 -9
  25. package/dist/core/config-reader.js.map +1 -1
  26. package/dist/core/endpoint-crawler.d.ts.map +1 -1
  27. package/dist/core/endpoint-crawler.js +15 -9
  28. package/dist/core/endpoint-crawler.js.map +1 -1
  29. package/dist/core/feedback-manager-solana.d.ts +93 -53
  30. package/dist/core/feedback-manager-solana.d.ts.map +1 -1
  31. package/dist/core/feedback-manager-solana.js +247 -140
  32. package/dist/core/feedback-manager-solana.js.map +1 -1
  33. package/dist/core/indexer-client.d.ts +285 -0
  34. package/dist/core/indexer-client.d.ts.map +1 -0
  35. package/dist/core/indexer-client.js +372 -0
  36. package/dist/core/indexer-client.js.map +1 -0
  37. package/dist/core/indexer-defaults.d.ts +23 -0
  38. package/dist/core/indexer-defaults.d.ts.map +1 -0
  39. package/dist/core/indexer-defaults.js +35 -0
  40. package/dist/core/indexer-defaults.js.map +1 -0
  41. package/dist/core/indexer-errors.d.ts +49 -0
  42. package/dist/core/indexer-errors.d.ts.map +1 -0
  43. package/dist/core/indexer-errors.js +67 -0
  44. package/dist/core/indexer-errors.js.map +1 -0
  45. package/dist/core/indexer-types.d.ts +87 -0
  46. package/dist/core/indexer-types.d.ts.map +1 -0
  47. package/dist/core/indexer-types.js +78 -0
  48. package/dist/core/indexer-types.js.map +1 -0
  49. package/dist/core/instruction-builder.d.ts +92 -26
  50. package/dist/core/instruction-builder.d.ts.map +1 -1
  51. package/dist/core/instruction-builder.js +240 -49
  52. package/dist/core/instruction-builder.js.map +1 -1
  53. package/dist/core/instruction-discriminators.d.ts +18 -1
  54. package/dist/core/instruction-discriminators.d.ts.map +1 -1
  55. package/dist/core/instruction-discriminators.js +19 -1
  56. package/dist/core/instruction-discriminators.js.map +1 -1
  57. package/dist/core/ipfs-client.d.ts +20 -0
  58. package/dist/core/ipfs-client.d.ts.map +1 -1
  59. package/dist/core/ipfs-client.js +194 -33
  60. package/dist/core/ipfs-client.js.map +1 -1
  61. package/dist/core/oasf-validator.d.ts +1 -0
  62. package/dist/core/oasf-validator.d.ts.map +1 -1
  63. package/dist/core/oasf-validator.js +32 -5
  64. package/dist/core/oasf-validator.js.map +1 -1
  65. package/dist/core/pda-helpers.d.ts +45 -53
  66. package/dist/core/pda-helpers.d.ts.map +1 -1
  67. package/dist/core/pda-helpers.js +60 -91
  68. package/dist/core/pda-helpers.js.map +1 -1
  69. package/dist/core/programs.d.ts +8 -0
  70. package/dist/core/programs.d.ts.map +1 -1
  71. package/dist/core/programs.js +9 -1
  72. package/dist/core/programs.js.map +1 -1
  73. package/dist/core/sdk-solana.d.ts +348 -106
  74. package/dist/core/sdk-solana.d.ts.map +1 -1
  75. package/dist/core/sdk-solana.js +707 -259
  76. package/dist/core/sdk-solana.js.map +1 -1
  77. package/dist/core/transaction-builder.d.ts +151 -45
  78. package/dist/core/transaction-builder.d.ts.map +1 -1
  79. package/dist/core/transaction-builder.js +615 -217
  80. package/dist/core/transaction-builder.js.map +1 -1
  81. package/dist/index.d.ts +11 -3
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +18 -2
  84. package/dist/index.js.map +1 -1
  85. package/dist/models/collection-metadata.d.ts +97 -0
  86. package/dist/models/collection-metadata.d.ts.map +1 -0
  87. package/dist/models/collection-metadata.js +72 -0
  88. package/dist/models/collection-metadata.js.map +1 -0
  89. package/dist/models/index.d.ts +1 -0
  90. package/dist/models/index.d.ts.map +1 -1
  91. package/dist/models/index.js +1 -0
  92. package/dist/models/index.js.map +1 -1
  93. package/dist/models/interfaces.d.ts +6 -28
  94. package/dist/models/interfaces.d.ts.map +1 -1
  95. package/dist/utils/constants.d.ts +6 -0
  96. package/dist/utils/constants.d.ts.map +1 -1
  97. package/dist/utils/constants.js +6 -0
  98. package/dist/utils/constants.js.map +1 -1
  99. package/dist/utils/index.d.ts +0 -1
  100. package/dist/utils/index.d.ts.map +1 -1
  101. package/dist/utils/index.js +0 -1
  102. package/dist/utils/index.js.map +1 -1
  103. package/dist/utils/logger.d.ts +19 -0
  104. package/dist/utils/logger.d.ts.map +1 -0
  105. package/dist/utils/logger.js +107 -0
  106. package/dist/utils/logger.js.map +1 -0
  107. package/dist/utils/registration-file-builder.d.ts.map +1 -1
  108. package/dist/utils/registration-file-builder.js +12 -2
  109. package/dist/utils/registration-file-builder.js.map +1 -1
  110. package/dist/utils/validation.d.ts +8 -20
  111. package/dist/utils/validation.d.ts.map +1 -1
  112. package/dist/utils/validation.js +94 -36
  113. package/dist/utils/validation.js.map +1 -1
  114. package/package.json +4 -6
  115. package/dist/core/feedback-auth.d.ts +0 -184
  116. package/dist/core/feedback-auth.d.ts.map +0 -1
  117. package/dist/core/feedback-auth.js +0 -232
  118. package/dist/core/feedback-auth.js.map +0 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Marco De Rossi
3
+ Copyright (c) 2025-2026 QuantuLabs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
  [![GitHub](https://img.shields.io/badge/GitHub-QuantuLabs%2F8004--solana-blue)](https://github.com/QuantuLabs/8004-solana)
9
9
  [![Solana Programs](https://img.shields.io/badge/Programs-8004--solana-purple)](https://github.com/QuantuLabs/8004-solana)
10
10
 
11
+ > **[How to register your first agent in 5 steps](./docs/quickstart.html)**
12
+
11
13
  ---
12
14
 
13
15
  ## About
@@ -52,7 +54,77 @@ const signer = Keypair.fromSecretKey(Uint8Array.from(privateKey));
52
54
  const sdk = new SolanaSDK({ signer });
53
55
  ```
54
56
 
55
- ### 2. Register an Agent
57
+ ### 2. Create a Collection (Optional)
58
+
59
+ Users can create their own collections to organize agents:
60
+
61
+ ```typescript
62
+ import {
63
+ SolanaSDK,
64
+ IPFSClient,
65
+ buildCollectionMetadataJson
66
+ } from '8004-solana';
67
+
68
+ // 1. Build collection metadata using the helper
69
+ const collectionData = buildCollectionMetadataJson({
70
+ name: 'My AI Agents',
71
+ description: 'Production AI agents for automation',
72
+ image: 'ipfs://QmLogo...',
73
+ category: 'automation',
74
+ tags: ['enterprise', 'api'],
75
+ project: {
76
+ name: 'Acme Corp',
77
+ socials: {
78
+ website: 'https://acme.ai',
79
+ x: 'acme_ai'
80
+ }
81
+ }
82
+ });
83
+
84
+ // 2. Upload metadata to IPFS
85
+ const ipfs = new IPFSClient({ pinataJwt: process.env.PINATA_JWT });
86
+ const collectionCid = await ipfs.addJson(collectionData);
87
+
88
+ // 3. Create collection on-chain
89
+ const sdk = new SolanaSDK({ signer });
90
+ const collectionResult = await sdk.createCollection(
91
+ collectionData.name, // Collection name (max 32 bytes)
92
+ `ipfs://${collectionCid}` // Collection metadata URI
93
+ );
94
+
95
+ console.log('Collection:', collectionResult.collection?.toBase58());
96
+
97
+ // 4. Register agents in your collection
98
+ const agentResult = await sdk.registerAgent(
99
+ 'ipfs://QmAgentMetadata...', // Agent metadata URI
100
+ collectionResult.collection // Your collection
101
+ );
102
+ ```
103
+
104
+ **Collection Metadata JSON Schema:**
105
+
106
+ ```json
107
+ {
108
+ "name": "Acme AI Agents",
109
+ "description": "Production-ready AI agents for enterprise automation",
110
+ "image": "ipfs://QmXxx.../logo.png",
111
+ "external_url": "https://acme.ai/agents",
112
+ "project": {
113
+ "name": "Acme Corporation",
114
+ "socials": {
115
+ "website": "https://acme.ai",
116
+ "x": "acme_ai",
117
+ "github": "acme-ai"
118
+ }
119
+ },
120
+ "category": "automation",
121
+ "tags": ["enterprise", "automation", "api"]
122
+ }
123
+ ```
124
+
125
+ > See full schemas: [`schemas/collection-metadata.schema.json`](schemas/collection-metadata.schema.json) and [`schemas/agent-metadata.schema.json`](schemas/agent-metadata.schema.json)
126
+
127
+ ### 3. Register an Agent (Detailed)
56
128
 
57
129
  **Step 1: Setup IPFS Client**
58
130
 
@@ -110,8 +182,15 @@ const metadataUri = `ipfs://${metadataCid}`;
110
182
 
111
183
  ```typescript
112
184
  const sdk = new SolanaSDK({ signer });
185
+
186
+ // Register in default collection
113
187
  const result = await sdk.registerAgent(metadataUri);
114
- console.log(`Agent #${result.agentId} registered!`);
188
+ console.log(`Agent registered! Asset: ${result.asset.toBase58()}`);
189
+
190
+ // Or register in your own collection
191
+ // Note: Only the collection creator can register agents in their collection
192
+ const myCollection = new PublicKey('YourCollectionPublicKey...');
193
+ const result2 = await sdk.registerAgent(metadataUri, myCollection);
115
194
  ```
116
195
 
117
196
  **Alternative: Use Web URLs**
@@ -130,11 +209,14 @@ const metadata = buildRegistrationFileJson({
130
209
  await sdk.registerAgent('https://my-server.com/agent-metadata.json');
131
210
  ```
132
211
 
133
- ### 3. Load Agent Data
212
+ ### 4. Load Agent Data
134
213
 
135
214
  ```typescript
136
- // Fetch agent by ID
137
- const agent = await sdk.loadAgent(agentId);
215
+ import { PublicKey } from '@solana/web3.js';
216
+
217
+ // Fetch agent by asset (PublicKey)
218
+ const agentAsset = new PublicKey('AgentAssetPublicKey...');
219
+ const agent = await sdk.loadAgent(agentAsset);
138
220
 
139
221
  if (agent) {
140
222
  console.log(`Name: ${agent.nft_name}`);
@@ -144,58 +226,56 @@ if (agent) {
144
226
  }
145
227
 
146
228
  // Or fetch all agents owned by a wallet (requires custom RPC)
147
- import { PublicKey } from '@solana/web3.js';
148
-
149
229
  const ownerWallet = new PublicKey('YourWalletAddress...');
150
230
  const myAgents = await sdk.getAgentsByOwner(ownerWallet);
151
231
 
152
232
  for (const agent of myAgents) {
153
- console.log(`Agent #${agent.agent_id}: ${agent.nft_name}`);
233
+ console.log(`Agent: ${agent.nft_name} (${agent.getAssetPublicKey().toBase58().slice(0,8)}...)`);
154
234
  }
155
235
  ```
156
236
 
157
- ### 4. Give Feedback
237
+ ### 5. Give Feedback
158
238
 
159
239
  ```typescript
160
240
  // Submit feedback for an agent (as a client/user)
161
241
  // Score is 0-100, tags are optional keywords
162
- await sdk.giveFeedback(agentId, {
163
- score: 85, // Rating out of 100
164
- tag1: 'helpful', // Optional: first tag
165
- tag2: 'accurate', // Optional: second tag
166
- fileUri: 'ipfs://QmFeedbackDetails', // Optional: detailed feedback file
167
- fileHash: Buffer.alloc(32), // Optional: SHA256 hash of file
242
+ await sdk.giveFeedback(agentAsset, {
243
+ score: 85, // Rating out of 100
244
+ tag1: 'helpful', // Optional: first tag
245
+ tag2: 'accurate', // Optional: second tag
246
+ feedbackUri: 'ipfs://QmFeedbackDetails', // Optional: detailed feedback file
247
+ feedbackHash: Buffer.alloc(32), // Optional: SHA256 hash of file
168
248
  });
169
249
  ```
170
250
 
171
- ### 5. Get Reputation
251
+ ### 6. Get Reputation
172
252
 
173
253
  ```typescript
174
254
  // Get aggregated reputation stats
175
- const summary = await sdk.getSummary(agentId);
255
+ const summary = await sdk.getSummary(agentAsset);
176
256
  console.log(`Average Score: ${summary.averageScore}/100`);
177
257
  console.log(`Total Feedbacks: ${summary.totalFeedbacks}`);
178
258
  console.log(`Next Index: ${summary.nextFeedbackIndex}`);
179
259
 
180
260
  // Read all individual feedbacks (requires custom RPC)
181
- const feedbacks = await sdk.readAllFeedback(agentId);
261
+ const feedbacks = await sdk.readAllFeedback(agentAsset);
182
262
  for (const fb of feedbacks) {
183
263
  console.log(`Score: ${fb.score}, Client: ${fb.client.toBase58()}`);
184
264
  }
185
265
  ```
186
266
 
187
- ### 6. Bulk Queries (Indexing)
267
+ ### 7. Bulk Queries (Indexer)
188
268
 
189
269
  ```typescript
190
270
  // Get ALL agents with their feedbacks in just 4 RPC calls
191
271
  const agents = await sdk.getAllAgents({ includeFeedbacks: true });
192
272
  for (const { account, feedbacks } of agents) {
193
- console.log(`Agent #${account.agent_id}: ${feedbacks?.length || 0} feedbacks`);
273
+ console.log(`Agent ${account.getAssetPublicKey().toBase58().slice(0,8)}...: ${feedbacks?.length || 0} feedbacks`);
194
274
  }
195
275
 
196
- // Or get ALL feedbacks separately as a Map
276
+ // Or get ALL feedbacks separately as a Map (keyed by asset string)
197
277
  const feedbacksMap = await sdk.getAllFeedbacks();
198
- const agent83Feedbacks = feedbacksMap.get(83n) || [];
278
+ const agentFeedbacks = feedbacksMap.get(agentAsset.toBase58()) || [];
199
279
  ```
200
280
 
201
281
  > **Note**: For advanced queries like `getAllAgents()`, `getAllFeedbacks()`, or `readAllFeedback()`, a custom RPC provider is required.
@@ -210,7 +290,7 @@ const agent83Feedbacks = feedbacksMap.get(83n) || [];
210
290
  - **[OASF Taxonomies](docs/OASF.md)** - Skills and domains reference
211
291
  - **[Changelog](docs/CHANGELOG.md)** - Version history and breaking changes
212
292
 
213
- **Program ID:** `HvF3JqhahcX7JfhbDRYYCJ7S3f6nJdrqu5yi9shyTREp`
293
+ **Program ID (Devnet):** `HHCVWcqsziJMmp43u2UAgAfH2cBjUFxVdW1M3C3NqzvT`
214
294
 
215
295
  ---
216
296
 
@@ -312,7 +392,7 @@ See the `examples/` directory for complete usage examples:
312
392
  | [`agent-update.ts`](examples/agent-update.ts) | On-chain metadata & URI update |
313
393
  | [`transfer-agent.ts`](examples/transfer-agent.ts) | Transfer agent ownership |
314
394
  | [`server-mode.ts`](examples/server-mode.ts) | Server/client architecture with skipSend |
315
- | [`basic-indexer.ts`](examples/basic-indexer.ts) | Index all agents to JSON file |
395
+ | [`basic-indexer.ts`](examples/basic-indexer.ts) | Indexer reference → [8004-solana-indexer](https://github.com/QuantuLabs/8004-solana-indexer) |
316
396
 
317
397
  Run examples:
318
398
  ```bash
@@ -352,4 +432,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
352
432
 
353
433
  ---
354
434
 
355
- **Built for the Solana ecosystem** | v0.2.2
435
+ **Built for the Solana ecosystem** | v0.4.0
@@ -1,44 +1,71 @@
1
1
  /**
2
- * Agent Mint Resolver
3
- * Resolves agent_id (bigint) to agent_mint (PublicKey) using Identity Registry accounts
2
+ * Agent Resolver
3
+ * v0.3.0 - Asset-based identification
4
4
  *
5
- * Strategy:
6
- * - Scan the Identity Registry program (not Metaplex!) for AgentAccount PDAs
7
- * - Each AgentAccount contains agent_id and agent_mint
8
- * - Load all agents once and cache for O(1) subsequent lookups
5
+ * NOTE: This class is largely deprecated in v0.3.0 since agents are now
6
+ * identified directly by their Metaplex Core asset pubkey, not by sequential IDs.
9
7
  *
10
- * This is MUCH faster than scanning Metaplex (millions of NFTs) because:
11
- * - Identity Registry has only ~27 agents vs millions of Metaplex metadata accounts
12
- * - Single getProgramAccounts call fetches all mappings
8
+ * The class is kept for backwards compatibility but most methods are deprecated.
9
+ * Use the asset pubkey directly instead of resolving from agent_id.
13
10
  */
14
11
  import { Connection, PublicKey } from '@solana/web3.js';
12
+ import { AgentAccount } from './borsh-schemas.js';
13
+ export interface LoadAgentsOptions {
14
+ /**
15
+ * Maximum number of accounts to load (default: 1000)
16
+ * Security: Prevents OOM from unbounded getProgramAccounts
17
+ */
18
+ maxAccounts?: number;
19
+ /**
20
+ * If true, throw on malformed accounts instead of skipping
21
+ * Default: false (skip malformed accounts with warning)
22
+ */
23
+ strictParsing?: boolean;
24
+ }
15
25
  /**
16
- * Agent Mint Resolver
17
- * Maps agent_id → agent_mint using Identity Registry accounts
26
+ * Agent Resolver
27
+ * v0.3.0 - Validates assets and loads agent accounts
28
+ *
29
+ * @deprecated In v0.3.0, agents are identified by their asset pubkey directly.
30
+ * Use asset pubkeys instead of agent_id numbers.
31
+ *
32
+ * Security: Thread-safety protection added in v0.3.0 - cache updates are atomic.
18
33
  */
19
34
  export declare class AgentMintResolver {
20
- private cache;
35
+ private assetCache;
21
36
  private connection;
22
37
  private cacheLoaded;
38
+ private loadingPromise;
23
39
  constructor(connection: Connection, _collectionMint?: PublicKey);
24
40
  /**
25
- * Resolve agent_id to agent_mint PublicKey
26
- * @param agentId - Sequential agent ID (0, 1, 2...)
27
- * @returns agent_mint PublicKey
28
- * @throws Error if agent not found
41
+ * @deprecated Use asset pubkey directly. In v0.3.0, agents are identified by asset, not agent_id.
42
+ *
43
+ * For backwards compatibility, this method now throws an error.
44
+ * Use getAgentByAsset() instead.
45
+ */
46
+ resolve(_agentId: bigint): Promise<PublicKey>;
47
+ /**
48
+ * Get AgentAccount by asset pubkey - v0.3.0
49
+ * @param asset - Metaplex Core asset pubkey
50
+ * @returns AgentAccount or null if not found
51
+ */
52
+ getAgentByAsset(asset: PublicKey): Promise<AgentAccount | null>;
53
+ /**
54
+ * Check if an asset is a registered agent
55
+ * @param asset - Metaplex Core asset pubkey
56
+ * @returns true if the asset is a registered agent
29
57
  */
30
- resolve(agentId: bigint): Promise<PublicKey>;
58
+ isRegisteredAgent(asset: PublicKey): Promise<boolean>;
31
59
  /**
32
- * Load all agents from Identity Registry and populate cache
33
- * This is much faster than scanning Metaplex (one RPC call vs millions of accounts)
60
+ * Load all agents from Identity Registry
61
+ * Security: Limited to maxAccounts (default 1000) to prevent OOM
34
62
  */
35
- private loadAllAgents;
63
+ loadAllAgents(options?: LoadAgentsOptions): Promise<Map<string, AgentAccount>>;
64
+ private doLoadAllAgents;
36
65
  /**
37
- * Manually add a mapping to cache (used after registration)
38
- * @param agentId - Agent ID
39
- * @param mint - Agent mint address
66
+ * @deprecated Use asset pubkey directly. No need to cache agent_id → asset mapping.
40
67
  */
41
- addToCache(agentId: bigint, mint: PublicKey): void;
68
+ addToCache(_agentId: bigint, _mint: PublicKey): void;
42
69
  /**
43
70
  * Clear the cache (useful for testing or forcing refresh)
44
71
  */
@@ -48,12 +75,9 @@ export declare class AgentMintResolver {
48
75
  */
49
76
  refresh(): Promise<void>;
50
77
  /**
51
- * Batch resolve multiple agent IDs
52
- * More efficient than resolving one at a time
53
- * @param agentIds - Array of agent IDs to resolve
54
- * @returns Map of agent_id → agent_mint
78
+ * @deprecated Use loadAllAgents() instead. Agent IDs no longer exist.
55
79
  */
56
- batchResolve(agentIds: bigint[]): Promise<Map<bigint, PublicKey>>;
80
+ batchResolve(_agentIds: bigint[]): Promise<Map<bigint, PublicKey>>;
57
81
  /**
58
82
  * Get cache size (number of loaded agents)
59
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"agent-mint-resolver.d.ts","sourceRoot":"","sources":["../../src/core/agent-mint-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAMxD;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAkB;gBAEzB,UAAU,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,SAAS;IAK/D;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAwBlD;;;OAGG;YACW,aAAa;IAuC3B;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAIlD;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAiBvE;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"agent-mint-resolver.d.ts","sourceRoot":"","sources":["../../src/core/agent-mint-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAYlD,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAwC;IAC1D,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAAmD;gBAE7D,UAAU,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,SAAS;IAI/D;;;;;OAKG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAQnD;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAyBrE;;;;OAIG;IACG,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3D;;;OAGG;IACG,aAAa,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YAS1E,eAAe;IAqE7B;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAIpD;;OAEG;IACH,UAAU,IAAI,IAAI;IAMlB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAOxE;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -1,63 +1,102 @@
1
1
  /**
2
- * Agent Mint Resolver
3
- * Resolves agent_id (bigint) to agent_mint (PublicKey) using Identity Registry accounts
2
+ * Agent Resolver
3
+ * v0.3.0 - Asset-based identification
4
4
  *
5
- * Strategy:
6
- * - Scan the Identity Registry program (not Metaplex!) for AgentAccount PDAs
7
- * - Each AgentAccount contains agent_id and agent_mint
8
- * - Load all agents once and cache for O(1) subsequent lookups
5
+ * NOTE: This class is largely deprecated in v0.3.0 since agents are now
6
+ * identified directly by their Metaplex Core asset pubkey, not by sequential IDs.
9
7
  *
10
- * This is MUCH faster than scanning Metaplex (millions of NFTs) because:
11
- * - Identity Registry has only ~27 agents vs millions of Metaplex metadata accounts
12
- * - Single getProgramAccounts call fetches all mappings
8
+ * The class is kept for backwards compatibility but most methods are deprecated.
9
+ * Use the asset pubkey directly instead of resolving from agent_id.
13
10
  */
14
11
  import { AgentAccount } from './borsh-schemas.js';
15
12
  import { ACCOUNT_DISCRIMINATORS } from './instruction-discriminators.js';
16
- import { IDENTITY_PROGRAM_ID } from './pda-helpers.js';
13
+ import { IDENTITY_PROGRAM_ID, PDAHelpers } from './pda-helpers.js';
14
+ import { logger } from '../utils/logger.js';
17
15
  import bs58 from 'bs58';
18
16
  /**
19
- * Agent Mint Resolver
20
- * Maps agent_id → agent_mint using Identity Registry accounts
17
+ * Security: Default limit for getProgramAccounts to prevent OOM
18
+ * For production with large agent registries, use an indexer instead.
19
+ */
20
+ const DEFAULT_MAX_ACCOUNTS = 1000;
21
+ /**
22
+ * Agent Resolver
23
+ * v0.3.0 - Validates assets and loads agent accounts
24
+ *
25
+ * @deprecated In v0.3.0, agents are identified by their asset pubkey directly.
26
+ * Use asset pubkeys instead of agent_id numbers.
27
+ *
28
+ * Security: Thread-safety protection added in v0.3.0 - cache updates are atomic.
21
29
  */
22
30
  export class AgentMintResolver {
31
+ assetCache = new Map();
32
+ connection;
33
+ cacheLoaded = false;
34
+ loadingPromise = null;
23
35
  constructor(connection, _collectionMint) {
24
- this.cache = new Map();
25
- this.cacheLoaded = false;
26
36
  this.connection = connection;
27
- // collectionMint is no longer needed (was for Metaplex filtering)
28
37
  }
29
38
  /**
30
- * Resolve agent_id to agent_mint PublicKey
31
- * @param agentId - Sequential agent ID (0, 1, 2...)
32
- * @returns agent_mint PublicKey
33
- * @throws Error if agent not found
39
+ * @deprecated Use asset pubkey directly. In v0.3.0, agents are identified by asset, not agent_id.
40
+ *
41
+ * For backwards compatibility, this method now throws an error.
42
+ * Use getAgentByAsset() instead.
34
43
  */
35
- async resolve(agentId) {
36
- const cacheKey = agentId.toString();
37
- // Check cache first (O(1))
38
- if (this.cache.has(cacheKey)) {
39
- return this.cache.get(cacheKey);
44
+ async resolve(_agentId) {
45
+ throw new Error('AgentMintResolver.resolve() is deprecated in v0.3.0. ' +
46
+ 'Agents are now identified by asset pubkey, not agent_id. ' +
47
+ 'Use asset pubkey directly or getAgentByAsset() to validate an asset.');
48
+ }
49
+ /**
50
+ * Get AgentAccount by asset pubkey - v0.3.0
51
+ * @param asset - Metaplex Core asset pubkey
52
+ * @returns AgentAccount or null if not found
53
+ */
54
+ async getAgentByAsset(asset) {
55
+ const cacheKey = asset.toBase58();
56
+ // Check cache first
57
+ if (this.assetCache.has(cacheKey)) {
58
+ return this.assetCache.get(cacheKey);
40
59
  }
41
- // If cache not loaded, load all agents from Identity Registry
42
- if (!this.cacheLoaded) {
43
- await this.loadAllAgents();
60
+ // Derive AgentAccount PDA
61
+ const [agentPda] = PDAHelpers.getAgentPDA(asset);
62
+ try {
63
+ const accountInfo = await this.connection.getAccountInfo(agentPda);
64
+ if (!accountInfo) {
65
+ return null;
66
+ }
67
+ const agentAccount = AgentAccount.deserialize(Buffer.from(accountInfo.data));
68
+ this.assetCache.set(cacheKey, agentAccount);
69
+ return agentAccount;
44
70
  }
45
- // Now check cache again
46
- const mint = this.cache.get(cacheKey);
47
- if (!mint) {
48
- throw new Error(`Agent #${agentId} not found. The agent may not exist.`);
71
+ catch {
72
+ return null;
49
73
  }
50
- return mint;
51
74
  }
52
75
  /**
53
- * Load all agents from Identity Registry and populate cache
54
- * This is much faster than scanning Metaplex (one RPC call vs millions of accounts)
76
+ * Check if an asset is a registered agent
77
+ * @param asset - Metaplex Core asset pubkey
78
+ * @returns true if the asset is a registered agent
55
79
  */
56
- async loadAllAgents() {
80
+ async isRegisteredAgent(asset) {
81
+ const agent = await this.getAgentByAsset(asset);
82
+ return agent !== null;
83
+ }
84
+ /**
85
+ * Load all agents from Identity Registry
86
+ * Security: Limited to maxAccounts (default 1000) to prevent OOM
87
+ */
88
+ async loadAllAgents(options = {}) {
89
+ if (this.loadingPromise) {
90
+ return await this.loadingPromise;
91
+ }
92
+ this.loadingPromise = this.doLoadAllAgents(options);
93
+ return await this.loadingPromise;
94
+ }
95
+ async doLoadAllAgents(options) {
96
+ const maxAccounts = options.maxAccounts ?? DEFAULT_MAX_ACCOUNTS;
97
+ const strictParsing = options.strictParsing ?? false;
57
98
  try {
58
- // Get AgentAccount discriminator bytes for filtering
59
99
  const discriminatorBytes = bs58.encode(ACCOUNT_DISCRIMINATORS.AgentAccount);
60
- // Fetch ALL AgentAccount PDAs from Identity Registry (single RPC call)
61
100
  const accounts = await this.connection.getProgramAccounts(IDENTITY_PROGRAM_ID, {
62
101
  filters: [
63
102
  {
@@ -68,41 +107,60 @@ export class AgentMintResolver {
68
107
  },
69
108
  ],
70
109
  });
71
- // Parse each account and populate cache
72
- for (const { account } of accounts) {
110
+ // Security: Warn if limit reached - may indicate need for indexer
111
+ const limitReached = accounts.length > maxAccounts;
112
+ if (limitReached) {
113
+ logger.warn(`getProgramAccounts returned ${accounts.length} agents, limiting to ${maxAccounts}. ` +
114
+ `Consider using an indexer for production.`);
115
+ }
116
+ // Security: Build in temp map, then atomic swap to prevent race conditions
117
+ const tempCache = new Map();
118
+ let skippedAccounts = 0;
119
+ const accountsToProcess = accounts.slice(0, maxAccounts);
120
+ for (const { account } of accountsToProcess) {
73
121
  try {
74
122
  const agentAccount = AgentAccount.deserialize(Buffer.from(account.data));
75
- const agentId = agentAccount.agent_id.toString();
76
- const agentMint = agentAccount.getMintPublicKey();
77
- this.cache.set(agentId, agentMint);
123
+ const assetPubkey = agentAccount.getAssetPublicKey();
124
+ tempCache.set(assetPubkey.toBase58(), agentAccount);
78
125
  }
79
- catch {
80
- // Skip malformed accounts
81
- continue;
126
+ catch (parseError) {
127
+ if (strictParsing) {
128
+ throw new Error(`Failed to parse AgentAccount: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);
129
+ }
130
+ skippedAccounts++;
82
131
  }
83
132
  }
133
+ // Security: Log warning if accounts were skipped (may indicate corruption)
134
+ if (skippedAccounts > 0) {
135
+ logger.warn(`Skipped ${skippedAccounts} malformed AgentAccount(s) during load. ` +
136
+ `Use strictParsing: true to fail on parse errors.`);
137
+ }
138
+ // Atomic swap - prevents race condition with concurrent reads
139
+ this.assetCache = tempCache;
84
140
  this.cacheLoaded = true;
85
- console.log(`AgentMintResolver: Loaded ${this.cache.size} agents from Identity Registry`);
141
+ this.loadingPromise = null;
142
+ return this.assetCache;
86
143
  }
87
144
  catch (error) {
88
- console.error(`Error loading agents from Identity Registry: ${error}`);
89
- throw new Error(`Failed to load agents: ${error}`);
145
+ this.loadingPromise = null;
146
+ // Security: Don't leak internal error details
147
+ logger.error('Failed to load agents from Identity Registry', error);
148
+ throw new Error('Failed to load agents from Identity Registry');
90
149
  }
91
150
  }
92
151
  /**
93
- * Manually add a mapping to cache (used after registration)
94
- * @param agentId - Agent ID
95
- * @param mint - Agent mint address
152
+ * @deprecated Use asset pubkey directly. No need to cache agent_id → asset mapping.
96
153
  */
97
- addToCache(agentId, mint) {
98
- this.cache.set(agentId.toString(), mint);
154
+ addToCache(_agentId, _mint) {
155
+ // No-op in v0.3.0
99
156
  }
100
157
  /**
101
158
  * Clear the cache (useful for testing or forcing refresh)
102
159
  */
103
160
  clearCache() {
104
- this.cache.clear();
161
+ this.assetCache.clear();
105
162
  this.cacheLoaded = false;
163
+ this.loadingPromise = null;
106
164
  }
107
165
  /**
108
166
  * Force reload all agents from chain
@@ -112,30 +170,17 @@ export class AgentMintResolver {
112
170
  await this.loadAllAgents();
113
171
  }
114
172
  /**
115
- * Batch resolve multiple agent IDs
116
- * More efficient than resolving one at a time
117
- * @param agentIds - Array of agent IDs to resolve
118
- * @returns Map of agent_id → agent_mint
173
+ * @deprecated Use loadAllAgents() instead. Agent IDs no longer exist.
119
174
  */
120
- async batchResolve(agentIds) {
121
- // Ensure cache is loaded
122
- if (!this.cacheLoaded) {
123
- await this.loadAllAgents();
124
- }
125
- const results = new Map();
126
- for (const agentId of agentIds) {
127
- const mint = this.cache.get(agentId.toString());
128
- if (mint) {
129
- results.set(agentId, mint);
130
- }
131
- }
132
- return results;
175
+ async batchResolve(_agentIds) {
176
+ throw new Error('AgentMintResolver.batchResolve() is deprecated in v0.3.0. ' +
177
+ 'Use loadAllAgents() to get all registered agents.');
133
178
  }
134
179
  /**
135
180
  * Get cache size (number of loaded agents)
136
181
  */
137
182
  get size() {
138
- return this.cache.size;
183
+ return this.assetCache.size;
139
184
  }
140
185
  }
141
186
  //# sourceMappingURL=agent-mint-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-mint-resolver.js","sourceRoot":"","sources":["../../src/core/agent-mint-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-mint-resolver.js","sourceRoot":"","sources":["../../src/core/agent-mint-resolver.ts"],"names":[],"mappings":"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"}