@ghostspeak/sdk 2.0.6 → 2.0.8

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/README.md +295 -30
  2. package/dist/GhostSpeakClient-bnXwUPHI.d.ts +1011 -0
  3. package/dist/StakingModule-DunDShLq.d.ts +2446 -0
  4. package/dist/{agent-M74TCRON.js → agent-S42FIMR7.js} +4 -4
  5. package/dist/{agent-M74TCRON.js.map → agent-S42FIMR7.js.map} +1 -1
  6. package/dist/batch-operations-45CQFEID.js +4 -0
  7. package/dist/batch-operations-45CQFEID.js.map +1 -0
  8. package/dist/browser-CI5_6Gzk.d.ts +234 -0
  9. package/dist/browser.d.ts +6 -576
  10. package/dist/browser.js +15 -842
  11. package/dist/browser.js.map +1 -1
  12. package/dist/chunk-46QWY3MG.js +156 -0
  13. package/dist/chunk-46QWY3MG.js.map +1 -0
  14. package/dist/{chunk-F3DZMBUA.js → chunk-5QBSC4T4.js} +327 -493
  15. package/dist/chunk-5QBSC4T4.js.map +1 -0
  16. package/dist/chunk-5QZVFUXB.js +4176 -0
  17. package/dist/chunk-5QZVFUXB.js.map +1 -0
  18. package/dist/chunk-6XCCMJ6M.js +1865 -0
  19. package/dist/chunk-6XCCMJ6M.js.map +1 -0
  20. package/dist/chunk-A7ALCVUI.js +98 -0
  21. package/dist/chunk-A7ALCVUI.js.map +1 -0
  22. package/dist/chunk-AWMGX3OX.js +814 -0
  23. package/dist/chunk-AWMGX3OX.js.map +1 -0
  24. package/dist/chunk-BF3IQ35I.js +284 -0
  25. package/dist/chunk-BF3IQ35I.js.map +1 -0
  26. package/dist/chunk-BQDGRTVP.js +168 -0
  27. package/dist/chunk-BQDGRTVP.js.map +1 -0
  28. package/dist/chunk-IQM5RASO.js +8502 -0
  29. package/dist/chunk-IQM5RASO.js.map +1 -0
  30. package/dist/chunk-JYXSOXCP.js +3850 -0
  31. package/dist/chunk-JYXSOXCP.js.map +1 -0
  32. package/dist/chunk-OXA7MECJ.js +7787 -0
  33. package/dist/chunk-OXA7MECJ.js.map +1 -0
  34. package/dist/chunk-QLRWUHN2.js +231 -0
  35. package/dist/chunk-QLRWUHN2.js.map +1 -0
  36. package/dist/chunk-SKMJJ3Q6.js +125 -0
  37. package/dist/chunk-SKMJJ3Q6.js.map +1 -0
  38. package/dist/chunk-TTB4OS2D.js +69 -0
  39. package/dist/chunk-TTB4OS2D.js.map +1 -0
  40. package/dist/chunk-UP2VWCW5.js +33 -0
  41. package/dist/{chunk-NSBPE2FW.js.map → chunk-UP2VWCW5.js.map} +1 -1
  42. package/dist/{chunk-UJUGGLMT.js → chunk-VQZQCHUT.js} +5 -5
  43. package/dist/{chunk-UJUGGLMT.js.map → chunk-VQZQCHUT.js.map} +1 -1
  44. package/dist/client.d.ts +4 -4
  45. package/dist/client.js +11 -10
  46. package/dist/createAgentAuthorization-KGZNXZBT.js +5 -0
  47. package/dist/createAgentAuthorization-KGZNXZBT.js.map +1 -0
  48. package/dist/credentials.js +1 -1
  49. package/dist/crypto.js +2 -2
  50. package/dist/errors.js +1 -1
  51. package/dist/feature-flags-B1g0DCPe.d.ts +1181 -0
  52. package/dist/generated-QJREJQ2C.js +9 -0
  53. package/dist/{generated-VNLHMR6Y.js.map → generated-QJREJQ2C.js.map} +1 -1
  54. package/dist/{ghostspeak_wasm-SB2RPJ3D.js → ghostspeak_wasm-F227HOSM.js} +3 -3
  55. package/dist/{ghostspeak_wasm-SB2RPJ3D.js.map → ghostspeak_wasm-F227HOSM.js.map} +1 -1
  56. package/dist/index.d.ts +1179 -1498
  57. package/dist/index.js +356 -3578
  58. package/dist/index.js.map +1 -1
  59. package/dist/metafile-esm.json +1 -1
  60. package/dist/minimal/core-minimal.d.ts +2446 -1245
  61. package/dist/minimal/core-minimal.js +9 -9
  62. package/dist/minimal/core-minimal.js.map +1 -1
  63. package/dist/nacl-fast-W5BJ3KZ2.js +2229 -0
  64. package/dist/nacl-fast-W5BJ3KZ2.js.map +1 -0
  65. package/dist/pda-4KP7CURF.js +4 -0
  66. package/dist/pda-4KP7CURF.js.map +1 -0
  67. package/dist/pda-Ce7VYg4T.d.ts +25 -0
  68. package/dist/reputation-types-Yebf0Rm_.d.ts +1071 -0
  69. package/dist/revokeAuthorization-2ZRO6GUZ.js +5 -0
  70. package/dist/revokeAuthorization-2ZRO6GUZ.js.map +1 -0
  71. package/dist/signature-verification-DGxR4aYQ.d.ts +448 -0
  72. package/dist/types.js +1 -1
  73. package/dist/updateReputationWithAuth-PCEUOCFV.js +5 -0
  74. package/dist/updateReputationWithAuth-PCEUOCFV.js.map +1 -0
  75. package/dist/utils.d.ts +69 -203
  76. package/dist/utils.js +15 -153
  77. package/dist/utils.js.map +1 -1
  78. package/package.json +27 -34
  79. package/dist/.tsbuildinfo +0 -1
  80. package/dist/GhostSpeakClient-D_66Uzsf.d.ts +0 -707
  81. package/dist/GovernanceModule-DQYYys-H.d.ts +0 -1766
  82. package/dist/chunk-APCKGD23.js +0 -1328
  83. package/dist/chunk-APCKGD23.js.map +0 -1
  84. package/dist/chunk-ASQXX4IT.js +0 -572
  85. package/dist/chunk-ASQXX4IT.js.map +0 -1
  86. package/dist/chunk-COGZFWOT.js +0 -19657
  87. package/dist/chunk-COGZFWOT.js.map +0 -1
  88. package/dist/chunk-F3DZMBUA.js.map +0 -1
  89. package/dist/chunk-GMHIUK2R.js +0 -7526
  90. package/dist/chunk-GMHIUK2R.js.map +0 -1
  91. package/dist/chunk-IAWBZYPE.js +0 -356
  92. package/dist/chunk-IAWBZYPE.js.map +0 -1
  93. package/dist/chunk-NSBPE2FW.js +0 -15
  94. package/dist/chunk-OWYHJG6H.js +0 -13311
  95. package/dist/chunk-OWYHJG6H.js.map +0 -1
  96. package/dist/chunk-RDDPOFR5.js +0 -3
  97. package/dist/chunk-RDDPOFR5.js.map +0 -1
  98. package/dist/chunk-RERCHKZP.js +0 -35
  99. package/dist/chunk-RERCHKZP.js.map +0 -1
  100. package/dist/chunk-TVVGXYCI.js +0 -2887
  101. package/dist/chunk-TVVGXYCI.js.map +0 -1
  102. package/dist/chunk-ZGP5552B.js +0 -377
  103. package/dist/chunk-ZGP5552B.js.map +0 -1
  104. package/dist/chunk-ZWOYNHVK.js +0 -196
  105. package/dist/chunk-ZWOYNHVK.js.map +0 -1
  106. package/dist/dist/.tsbuildinfo +0 -1
  107. package/dist/elgamal-VZLWB3XK.js +0 -5
  108. package/dist/elgamal-VZLWB3XK.js.map +0 -1
  109. package/dist/feature-flags-V722ZuXO.d.ts +0 -3512
  110. package/dist/generated-VNLHMR6Y.js +0 -5
  111. package/dist/ipfs-types-BOt9ZNg4.d.ts +0 -592
  112. package/dist/multisigConfig-BzEhy6jy.d.ts +0 -58
  113. package/dist/pda-B_nS8SbD.d.ts +0 -114
  114. package/dist/pda-S4BFJVGE.js +0 -4
  115. package/dist/pda-S4BFJVGE.js.map +0 -1
  116. package/dist/system-addresses-BFNLEbFx.d.ts +0 -857
  117. package/dist/token-2022-rpc-RALH4RK7.js +0 -593
  118. package/dist/token-2022-rpc-RALH4RK7.js.map +0 -1
@@ -0,0 +1,3850 @@
1
+ import { init_reputation_tag_engine, createErrorContext, logEnhancedError, IPFSClient, SYSTEM_PROGRAM_ADDRESS, ReputationCalculator, ReputationTagEngine, REPUTATION_CONSTANTS } from './chunk-OXA7MECJ.js';
2
+ import { getInitializeGovernanceProposalInstructionAsync, getInitializeStakingConfigInstructionAsync, getStakeGhostInstructionAsync, getUnstakeGhostInstructionAsync, getRegisterAgentInstructionAsync, getRegisterAgentCompressedInstructionAsync, getUpdateAgentInstruction, getVerifyAgentInstructionAsync, getDeactivateAgentInstruction, getActivateAgentInstruction, getClaimGhostInstruction } from './chunk-IQM5RASO.js';
3
+ import { __export, __esm } from './chunk-UP2VWCW5.js';
4
+ import { createSolanaRpc, createSolanaRpcSubscriptions, lamports, pipe, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, signTransactionMessageWithSigners, setTransactionMessageFeePayer, compileTransactionMessage, getBase64EncodedWireTransaction, getProgramDerivedAddress, getUtf8Encoder, getAddressEncoder } from '@solana/kit';
5
+ import { LRUCache } from 'lru-cache';
6
+ import { address } from '@solana/addresses';
7
+ import bs58 from 'bs58';
8
+ import { sha256 } from '@noble/hashes/sha256';
9
+
10
+ // src/modules/reputation/MultiSourceAggregator.ts
11
+ var MultiSourceAggregator_exports = {};
12
+ __export(MultiSourceAggregator_exports, {
13
+ MultiSourceAggregator: () => MultiSourceAggregator
14
+ });
15
+ var MultiSourceAggregator;
16
+ var init_MultiSourceAggregator = __esm({
17
+ "src/modules/reputation/MultiSourceAggregator.ts"() {
18
+ MultiSourceAggregator = class {
19
+ adapters = /* @__PURE__ */ new Map();
20
+ configs = /* @__PURE__ */ new Map();
21
+ /** Conflict threshold (30% variance) */
22
+ CONFLICT_THRESHOLD = 300;
23
+ // 30% of 1000 scale
24
+ /**
25
+ * Create a new multi-source aggregator
26
+ */
27
+ constructor() {
28
+ }
29
+ /**
30
+ * Add a reputation source
31
+ *
32
+ * @param adapter - Reputation source adapter
33
+ * @param config - Source configuration
34
+ */
35
+ addSource(adapter, config) {
36
+ if (!config.enabled) {
37
+ return;
38
+ }
39
+ this.adapters.set(adapter.source, adapter);
40
+ this.configs.set(adapter.source, config);
41
+ }
42
+ /**
43
+ * Remove a reputation source
44
+ *
45
+ * @param source - Source to remove
46
+ */
47
+ removeSource(source) {
48
+ this.adapters.delete(source);
49
+ this.configs.delete(source);
50
+ }
51
+ /**
52
+ * Update source weight
53
+ *
54
+ * @param source - Source to update
55
+ * @param weight - New weight in basis points (0-10000)
56
+ */
57
+ updateSourceWeight(source, weight) {
58
+ const config = this.configs.get(source);
59
+ if (config) {
60
+ config.weight = weight;
61
+ }
62
+ }
63
+ /**
64
+ * Update source reliability
65
+ *
66
+ * @param source - Source to update
67
+ * @param reliability - New reliability in basis points (0-10000)
68
+ */
69
+ updateSourceReliability(source, reliability) {
70
+ const config = this.configs.get(source);
71
+ if (config) {
72
+ config.reliability = reliability;
73
+ }
74
+ }
75
+ /**
76
+ * Aggregate reputation from all sources
77
+ *
78
+ * @param agentId - Agent identifier
79
+ * @returns Aggregated reputation data
80
+ */
81
+ async aggregateReputation(agentId) {
82
+ const sourceDataList = [];
83
+ for (const [source, adapter] of this.adapters.entries()) {
84
+ try {
85
+ const data = await adapter.fetchReputationData(agentId.toString());
86
+ if (adapter.validateData(data)) {
87
+ sourceDataList.push(data);
88
+ }
89
+ } catch (error) {
90
+ console.warn(`Failed to fetch reputation from ${source}:`, error);
91
+ }
92
+ }
93
+ const aggregateScore = this.calculateWeightedScore(sourceDataList);
94
+ const { hasConflicts, conflicts } = this.detectConflicts(sourceDataList);
95
+ const sourceScores = this.buildSourceBreakdowns(sourceDataList);
96
+ const totalDataPoints = sourceDataList.reduce((sum, data) => sum + data.dataPoints, 0);
97
+ return {
98
+ agentId,
99
+ aggregateScore,
100
+ sourceScores,
101
+ hasConflicts,
102
+ conflicts,
103
+ totalDataPoints,
104
+ timestamp: /* @__PURE__ */ new Date()
105
+ };
106
+ }
107
+ /**
108
+ * Calculate weighted aggregate score
109
+ *
110
+ * Formula: Σ(score × weight × reliability) / Σ(weight × reliability)
111
+ *
112
+ * @param sourceDataList - Data from all sources
113
+ * @returns Weighted aggregate score (0-1000)
114
+ */
115
+ calculateWeightedScore(sourceDataList) {
116
+ if (sourceDataList.length === 0) {
117
+ return 0;
118
+ }
119
+ let totalContribution = 0;
120
+ let totalNormalization = 0;
121
+ for (const data of sourceDataList) {
122
+ const config = this.configs.get(data.source);
123
+ if (!config) continue;
124
+ const weight = config.weight / 1e4;
125
+ const reliability = data.reliability;
126
+ const contribution = data.score * weight * reliability;
127
+ const normalization = weight * reliability;
128
+ totalContribution += contribution;
129
+ totalNormalization += normalization;
130
+ }
131
+ if (totalNormalization === 0) {
132
+ return 0;
133
+ }
134
+ return Math.round(totalContribution / totalNormalization);
135
+ }
136
+ /**
137
+ * Detect conflicts between sources
138
+ *
139
+ * Flags conflicts if max_score - min_score > 30%
140
+ *
141
+ * @param sourceDataList - Data from all sources
142
+ * @returns Conflict detection result
143
+ */
144
+ detectConflicts(sourceDataList) {
145
+ if (sourceDataList.length < 2) {
146
+ return { hasConflicts: false, conflicts: [] };
147
+ }
148
+ const scores = sourceDataList.map((d) => d.score);
149
+ const maxScore = Math.max(...scores);
150
+ const minScore = Math.min(...scores);
151
+ const variance = maxScore - minScore;
152
+ const conflicts = [];
153
+ if (variance > this.CONFLICT_THRESHOLD) {
154
+ const maxSource = sourceDataList.find((d) => d.score === maxScore)?.source;
155
+ const minSource = sourceDataList.find((d) => d.score === minScore)?.source;
156
+ conflicts.push(
157
+ `High variance detected: ${variance} (${(variance / 1e3 * 100).toFixed(1)}%) between ${maxSource} (${maxScore}) and ${minSource} (${minScore})`
158
+ );
159
+ return { hasConflicts: true, conflicts };
160
+ }
161
+ return { hasConflicts: false, conflicts: [] };
162
+ }
163
+ /**
164
+ * Build source score breakdowns
165
+ *
166
+ * @param sourceDataList - Data from all sources
167
+ * @returns Source score breakdowns
168
+ */
169
+ buildSourceBreakdowns(sourceDataList) {
170
+ return sourceDataList.map((data) => {
171
+ const config = this.configs.get(data.source);
172
+ if (!config) {
173
+ throw new Error(`No config found for source: ${data.source}`);
174
+ }
175
+ const weight = config.weight;
176
+ const reliability = data.reliability * 1e4;
177
+ const contribution = data.score * (weight / 1e4) * (reliability / 1e4) / this.calculateNormalizationFactor(sourceDataList);
178
+ return {
179
+ source: data.source,
180
+ score: data.score,
181
+ weight,
182
+ reliability: Math.round(reliability),
183
+ dataPoints: data.dataPoints,
184
+ contribution: Math.round(contribution),
185
+ lastUpdated: data.timestamp
186
+ };
187
+ });
188
+ }
189
+ /**
190
+ * Calculate normalization factor for weighted scoring
191
+ */
192
+ calculateNormalizationFactor(sourceDataList) {
193
+ let total = 0;
194
+ for (const data of sourceDataList) {
195
+ const config = this.configs.get(data.source);
196
+ if (!config) continue;
197
+ const weight = config.weight / 1e4;
198
+ const reliability = data.reliability;
199
+ total += weight * reliability;
200
+ }
201
+ return total || 1;
202
+ }
203
+ /**
204
+ * Get detailed source breakdown for an agent
205
+ *
206
+ * @param agentId - Agent identifier
207
+ * @returns Source breakdowns with full details
208
+ */
209
+ async getSourceBreakdown(agentId) {
210
+ const result = await this.aggregateReputation(agentId);
211
+ return result.sourceScores;
212
+ }
213
+ /**
214
+ * Get list of registered sources
215
+ */
216
+ getRegisteredSources() {
217
+ return Array.from(this.adapters.keys());
218
+ }
219
+ /**
220
+ * Get source configuration
221
+ *
222
+ * @param source - Source identifier
223
+ * @returns Source configuration or undefined
224
+ */
225
+ getSourceConfig(source) {
226
+ return this.configs.get(source);
227
+ }
228
+ /**
229
+ * Enable a source
230
+ *
231
+ * @param source - Source to enable
232
+ */
233
+ enableSource(source) {
234
+ const config = this.configs.get(source);
235
+ if (config) {
236
+ config.enabled = true;
237
+ }
238
+ }
239
+ /**
240
+ * Disable a source
241
+ *
242
+ * @param source - Source to disable
243
+ */
244
+ disableSource(source) {
245
+ const config = this.configs.get(source);
246
+ if (config) {
247
+ config.enabled = false;
248
+ }
249
+ }
250
+ /**
251
+ * Check if source is enabled
252
+ *
253
+ * @param source - Source to check
254
+ * @returns True if enabled
255
+ */
256
+ isSourceEnabled(source) {
257
+ const config = this.configs.get(source);
258
+ return config?.enabled ?? false;
259
+ }
260
+ };
261
+ }
262
+ });
263
+ var RpcClient = class {
264
+ rpc;
265
+ rpcSubscriptions;
266
+ commitment;
267
+ endpoint;
268
+ maxRetries;
269
+ retryDelay;
270
+ timeout;
271
+ constructor(config) {
272
+ this.endpoint = config.endpoint;
273
+ this.rpc = createSolanaRpc(config.endpoint);
274
+ this.commitment = config.commitment ?? "confirmed";
275
+ this.maxRetries = config.maxRetries ?? 3;
276
+ this.retryDelay = config.retryDelay ?? 1e3;
277
+ this.timeout = config.timeout ?? 6e4;
278
+ if (config.wsEndpoint) {
279
+ this.rpcSubscriptions = createSolanaRpcSubscriptions(config.wsEndpoint);
280
+ }
281
+ }
282
+ /**
283
+ * Get account information with automatic retries
284
+ */
285
+ async getAccountInfo(address2, options) {
286
+ return this.withRetry(async () => {
287
+ const result = await this.rpc.getAccountInfo(address2, {
288
+ commitment: options?.commitment ?? this.commitment,
289
+ encoding: "base64"
290
+ }).send();
291
+ if (!result.value) return null;
292
+ return this.parseAccountInfo(result.value);
293
+ });
294
+ }
295
+ /**
296
+ * Get multiple accounts efficiently
297
+ */
298
+ async getMultipleAccounts(addresses, options) {
299
+ return this.withRetry(async () => {
300
+ const result = await this.rpc.getMultipleAccounts(addresses, {
301
+ commitment: options?.commitment ?? this.commitment,
302
+ encoding: "base64"
303
+ }).send();
304
+ return result.value.map(
305
+ (account) => account ? this.parseAccountInfo(account) : null
306
+ );
307
+ });
308
+ }
309
+ /**
310
+ * Get program accounts with filters
311
+ */
312
+ async getProgramAccounts(programId, options) {
313
+ return this.withRetry(async () => {
314
+ const result = await this.rpc.getProgramAccounts(programId, {
315
+ commitment: options?.commitment ?? this.commitment,
316
+ encoding: "base64",
317
+ filters: options?.filters
318
+ }).send();
319
+ return result.map((item) => {
320
+ const typedItem = item;
321
+ return {
322
+ pubkey: typedItem.pubkey,
323
+ account: this.parseAccountInfo(typedItem.account)
324
+ };
325
+ });
326
+ });
327
+ }
328
+ /**
329
+ * Get latest blockhash with automatic caching
330
+ */
331
+ blockhashCache = null;
332
+ async getLatestBlockhash() {
333
+ const now = Date.now();
334
+ if (this.blockhashCache && now - this.blockhashCache.timestamp < 1e3) {
335
+ return this.blockhashCache.value;
336
+ }
337
+ const result = await this.withRetry(async () => {
338
+ const response = await this.rpc.getLatestBlockhash({
339
+ commitment: this.commitment
340
+ }).send();
341
+ return {
342
+ blockhash: response.value.blockhash,
343
+ lastValidBlockHeight: BigInt(response.value.lastValidBlockHeight)
344
+ };
345
+ });
346
+ this.blockhashCache = { value: result, timestamp: now };
347
+ return result;
348
+ }
349
+ /**
350
+ * Send transaction with enhanced error handling
351
+ */
352
+ async sendTransaction(transaction, options) {
353
+ return this.withRetry(async () => {
354
+ const result = await this.rpc.sendTransaction(transaction, {
355
+ encoding: "base64",
356
+ skipPreflight: options?.skipPreflight ?? false,
357
+ preflightCommitment: options?.preflightCommitment ?? this.commitment,
358
+ maxRetries: options?.maxRetries ? BigInt(options.maxRetries) : void 0
359
+ }).send();
360
+ return result;
361
+ });
362
+ }
363
+ /**
364
+ * Get signature statuses with batch support
365
+ */
366
+ async getSignatureStatuses(signatures) {
367
+ return this.withRetry(async () => {
368
+ const result = await this.rpc.getSignatureStatuses(signatures).send();
369
+ return result.value.map((status) => {
370
+ if (!status) return null;
371
+ const typedStatus = status;
372
+ return {
373
+ slot: typedStatus.slot,
374
+ confirmations: typedStatus.confirmations,
375
+ err: typedStatus.err,
376
+ confirmationStatus: typedStatus.confirmationStatus
377
+ };
378
+ });
379
+ });
380
+ }
381
+ /**
382
+ * Simulate transaction with detailed error info
383
+ */
384
+ async simulateTransaction(transaction, options) {
385
+ return this.withRetry(async () => {
386
+ const result = await this.rpc.simulateTransaction(transaction, {
387
+ encoding: "base64",
388
+ commitment: options?.commitment ?? this.commitment,
389
+ replaceRecentBlockhash: options?.replaceRecentBlockhash ?? false
390
+ }).send();
391
+ return {
392
+ err: result.value.err,
393
+ logs: result.value.logs ?? [],
394
+ unitsConsumed: result.value.unitsConsumed ? BigInt(result.value.unitsConsumed) : void 0,
395
+ returnData: result.value.returnData
396
+ };
397
+ });
398
+ }
399
+ /**
400
+ * Get fee for message
401
+ */
402
+ async getFeeForMessage(encodedMessage) {
403
+ return this.withRetry(async () => {
404
+ const result = await this.rpc.getFeeForMessage(encodedMessage, {
405
+ commitment: this.commitment
406
+ }).send();
407
+ return result.value ? BigInt(result.value) : null;
408
+ });
409
+ }
410
+ /**
411
+ * Health check
412
+ */
413
+ async isHealthy() {
414
+ try {
415
+ await this.rpc.getHealth().send();
416
+ return true;
417
+ } catch {
418
+ return false;
419
+ }
420
+ }
421
+ /**
422
+ * Get RPC node version
423
+ */
424
+ async getVersion() {
425
+ const result = await this.rpc.getVersion().send();
426
+ return result;
427
+ }
428
+ /**
429
+ * Subscribe to account changes (WebSocket)
430
+ * Note: This is a placeholder implementation. In production, you would use the actual subscription API
431
+ */
432
+ async subscribeToAccount(address2, callback) {
433
+ if (!this.rpcSubscriptions) {
434
+ throw new Error("WebSocket endpoint not configured");
435
+ }
436
+ console.warn("Account subscription is not fully implemented in this version");
437
+ const intervalId = setInterval(async () => {
438
+ try {
439
+ const accountInfo = await this.getAccountInfo(address2);
440
+ callback(accountInfo);
441
+ } catch (error) {
442
+ console.error("Subscription polling error:", error);
443
+ }
444
+ }, 5e3);
445
+ return () => {
446
+ clearInterval(intervalId);
447
+ };
448
+ }
449
+ // Private helper methods
450
+ async withRetry(operation, retries = this.maxRetries) {
451
+ let lastError;
452
+ for (let i = 0; i <= retries; i++) {
453
+ try {
454
+ return await operation();
455
+ } catch (error) {
456
+ lastError = error;
457
+ if (i < retries) {
458
+ await new Promise((resolve) => setTimeout(resolve, this.retryDelay * Math.pow(2, i)));
459
+ }
460
+ }
461
+ }
462
+ throw lastError;
463
+ }
464
+ parseAccountInfo(rawAccount) {
465
+ const account = rawAccount;
466
+ const dataArray = account.data;
467
+ const base64Data = Array.isArray(dataArray) ? dataArray[0] : dataArray;
468
+ return {
469
+ executable: account.executable,
470
+ lamports: typeof account.lamports === "number" ? lamports(BigInt(account.lamports)) : account.lamports,
471
+ owner: account.owner,
472
+ rentEpoch: account.rentEpoch !== void 0 ? typeof account.rentEpoch === "number" ? BigInt(account.rentEpoch) : account.rentEpoch : BigInt(0),
473
+ data: Buffer.from(base64Data, "base64"),
474
+ space: account.space ? typeof account.space === "number" ? BigInt(account.space) : account.space : void 0
475
+ };
476
+ }
477
+ };
478
+
479
+ // src/utils/transaction-urls.ts
480
+ function getSolanaExplorerUrl(signature, cluster = "mainnet-beta") {
481
+ const baseUrl = "https://explorer.solana.com/tx";
482
+ switch (cluster) {
483
+ case "devnet":
484
+ return `${baseUrl}/${signature}?cluster=devnet`;
485
+ case "testnet":
486
+ return `${baseUrl}/${signature}?cluster=testnet`;
487
+ case "localnet":
488
+ return `${baseUrl}/${signature}?cluster=custom&customUrl=http://localhost:8899`;
489
+ default:
490
+ return `${baseUrl}/${signature}`;
491
+ }
492
+ }
493
+ function getSolscanUrl(signature, cluster = "mainnet-beta") {
494
+ const baseUrl = "https://solscan.io/tx";
495
+ switch (cluster) {
496
+ case "devnet":
497
+ return `${baseUrl}/${signature}?cluster=devnet`;
498
+ case "testnet":
499
+ return `${baseUrl}/${signature}?cluster=testnet`;
500
+ case "localnet":
501
+ return `Local transaction: ${signature} (not viewable on Solscan)`;
502
+ default:
503
+ return `${baseUrl}/${signature}`;
504
+ }
505
+ }
506
+ function getSolanaFMUrl(signature, cluster = "mainnet-beta") {
507
+ const baseUrl = "https://solana.fm/tx";
508
+ switch (cluster) {
509
+ case "devnet":
510
+ return `${baseUrl}/${signature}?cluster=devnet-solana`;
511
+ case "testnet":
512
+ return `${baseUrl}/${signature}?cluster=testnet-solana`;
513
+ case "localnet":
514
+ return `Local transaction: ${signature} (not viewable on SolanaFM)`;
515
+ default:
516
+ return `${baseUrl}/${signature}`;
517
+ }
518
+ }
519
+ function getXrayUrl(signature, cluster = "mainnet-beta") {
520
+ const baseUrl = "https://xray.helius.xyz/tx";
521
+ switch (cluster) {
522
+ case "devnet":
523
+ return `${baseUrl}/${signature}?network=devnet`;
524
+ case "testnet":
525
+ return `${baseUrl}/${signature}?network=testnet`;
526
+ case "localnet":
527
+ return `Local transaction: ${signature} (not viewable on XRAY)`;
528
+ default:
529
+ return `${baseUrl}/${signature}`;
530
+ }
531
+ }
532
+ function generateExplorerUrls(signature, cluster = "mainnet-beta") {
533
+ return {
534
+ solanaExplorer: getSolanaExplorerUrl(signature, cluster),
535
+ solscan: getSolscanUrl(signature, cluster),
536
+ solanaFM: getSolanaFMUrl(signature, cluster),
537
+ xray: getXrayUrl(signature, cluster)
538
+ };
539
+ }
540
+ function createTransactionResult(signature, cluster, commitment = "confirmed") {
541
+ return {
542
+ signature,
543
+ cluster,
544
+ urls: generateExplorerUrls(signature, cluster),
545
+ commitment,
546
+ timestamp: Date.now()
547
+ };
548
+ }
549
+
550
+ // src/core/DevTools.ts
551
+ var DevTools = class _DevTools {
552
+ static instance = null;
553
+ rpcClient;
554
+ config;
555
+ isDevelopment;
556
+ logs = [];
557
+ timings = /* @__PURE__ */ new Map();
558
+ constructor(config) {
559
+ this.config = config;
560
+ this.rpcClient = new RpcClient({
561
+ endpoint: config.rpcEndpoint ?? "https://api.devnet.solana.com",
562
+ commitment: config.commitment
563
+ });
564
+ this.isDevelopment = process.env.NODE_ENV === "development" || config.cluster === "localnet" || false;
565
+ }
566
+ /**
567
+ * Get singleton instance
568
+ */
569
+ static getInstance(config) {
570
+ if (!_DevTools.instance && config) {
571
+ _DevTools.instance = new _DevTools(config);
572
+ }
573
+ if (!_DevTools.instance) {
574
+ throw new Error("DevTools not initialized. Call with config first.");
575
+ }
576
+ return _DevTools.instance;
577
+ }
578
+ /**
579
+ * Enable development mode
580
+ */
581
+ enableDevMode() {
582
+ this.isDevelopment = true;
583
+ console.log("\u{1F6E0}\uFE0F GhostSpeak Development Mode Enabled");
584
+ console.log(" - Transaction simulation before sending");
585
+ console.log(" - Cost estimates for all operations");
586
+ console.log(" - Enhanced error messages");
587
+ console.log(" - Performance timing");
588
+ }
589
+ /**
590
+ * Check if in development mode
591
+ */
592
+ isDevMode() {
593
+ return this.isDevelopment;
594
+ }
595
+ /**
596
+ * Analyze transaction instructions
597
+ */
598
+ analyzeTransaction(instructions) {
599
+ const writableAccounts = /* @__PURE__ */ new Set();
600
+ const readonlyAccounts = /* @__PURE__ */ new Set();
601
+ const signers = /* @__PURE__ */ new Set();
602
+ const warnings = [];
603
+ let totalSize = 64;
604
+ const instructionAnalyses = instructions.map((instr, index) => {
605
+ totalSize += 32;
606
+ totalSize += (instr.accounts?.length ?? 0) * 32;
607
+ totalSize += instr.data?.length ?? 0;
608
+ const accounts = (instr.accounts ?? []).map((acc) => {
609
+ const isWritable = acc.role.toString().includes("writable") || acc.role.toString().includes("WRITABLE") || acc.role === 1 || // AccountRole.WRITABLE = 1
610
+ acc.role === 3;
611
+ const isSigner = acc.role.toString().includes("signer") || acc.role.toString().includes("SIGNER") || typeof acc === "object" && "signer" in acc || acc.role === 3;
612
+ if (isWritable) {
613
+ writableAccounts.add(acc.address);
614
+ } else {
615
+ readonlyAccounts.add(acc.address);
616
+ }
617
+ if (isSigner) {
618
+ signers.add(acc.address);
619
+ }
620
+ return {
621
+ address: acc.address,
622
+ isWritable,
623
+ isSigner,
624
+ role: acc.role
625
+ };
626
+ });
627
+ const humanReadable = this.getInstructionDescription(instr, index);
628
+ return {
629
+ index,
630
+ programId: instr.programAddress,
631
+ accountCount: accounts.length,
632
+ dataSize: instr.data?.length ?? 0,
633
+ humanReadable,
634
+ accounts
635
+ };
636
+ });
637
+ const estimatedComputeUnits = this.estimateComputeUnits(instructions);
638
+ const estimatedFee = this.estimateFee(estimatedComputeUnits, instructions.length);
639
+ if (totalSize > 1232) {
640
+ warnings.push(`Transaction size (${totalSize} bytes) exceeds limit (1232 bytes)`);
641
+ }
642
+ if (signers.size === 0) {
643
+ warnings.push("No signers found in transaction");
644
+ }
645
+ if (estimatedComputeUnits > BigInt(14e5)) {
646
+ warnings.push(`High compute usage: ${estimatedComputeUnits} units`);
647
+ }
648
+ return {
649
+ instructions: instructionAnalyses,
650
+ totalAccounts: writableAccounts.size + readonlyAccounts.size,
651
+ signerCount: signers.size,
652
+ writableAccounts: Array.from(writableAccounts),
653
+ readonlyAccounts: Array.from(readonlyAccounts),
654
+ estimatedSize: totalSize,
655
+ estimatedComputeUnits,
656
+ estimatedFee,
657
+ warnings
658
+ };
659
+ }
660
+ /**
661
+ * Get human-readable instruction description
662
+ */
663
+ getInstructionDescription(instruction, _index) {
664
+ const programId = instruction.programAddress;
665
+ if (programId === this.config.programId) {
666
+ return this.decodeGhostSpeakInstruction(instruction);
667
+ }
668
+ if (programId === "11111111111111111111111111111111") {
669
+ return "System Program: Transfer or Create Account";
670
+ }
671
+ if (programId === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") {
672
+ return "Token Program: Token Operation";
673
+ }
674
+ if (programId === "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb") {
675
+ return "Token-2022 Program: Advanced Token Operation";
676
+ }
677
+ return `Unknown Instruction`;
678
+ }
679
+ /**
680
+ * Decode GhostSpeak instruction
681
+ */
682
+ decodeGhostSpeakInstruction(instruction) {
683
+ if (!instruction.data || instruction.data.length < 8) {
684
+ return "GhostSpeak: Unknown Instruction";
685
+ }
686
+ const discriminator = Array.from(instruction.data.slice(0, 8)).map((b) => b.toString(16).padStart(2, "0")).join("");
687
+ const instructionMap = {
688
+ "a8c5e109d3d1b8d5": "Register Agent",
689
+ "b7f3c8e0a2d4e9f1": "Create Escrow",
690
+ "c4d2f7a9b8e1c3f5": "Send Message",
691
+ "d9e8f2b5c1a7e4f8": "Create Channel"
692
+ // Add more mappings as needed
693
+ };
694
+ return `GhostSpeak: ${instructionMap[discriminator] ?? "Custom Instruction"}`;
695
+ }
696
+ /**
697
+ * Estimate compute units for instructions
698
+ */
699
+ estimateComputeUnits(instructions) {
700
+ let totalUnits = BigInt(0);
701
+ for (const instr of instructions) {
702
+ totalUnits += BigInt(200);
703
+ totalUnits += BigInt((instr.accounts?.length ?? 0) * 150);
704
+ totalUnits += BigInt((instr.data?.length ?? 0) * 10);
705
+ if (instr.programAddress === this.config.programId) {
706
+ totalUnits += BigInt(5e3);
707
+ }
708
+ }
709
+ return totalUnits;
710
+ }
711
+ /**
712
+ * Estimate transaction fee
713
+ */
714
+ estimateFee(computeUnits, instructionCount) {
715
+ const baseFee = BigInt(5e3);
716
+ const computeFee = computeUnits * BigInt(5) / BigInt(1e6);
717
+ const priorityFee = BigInt(instructionCount * 1e3);
718
+ return baseFee + computeFee + priorityFee;
719
+ }
720
+ /**
721
+ * Log debug message
722
+ */
723
+ log(message, data) {
724
+ if (!this.isDevelopment) return;
725
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
726
+ const logEntry = `[${timestamp}] ${message}`;
727
+ this.logs.push(logEntry);
728
+ console.log(`\u{1F50D} ${logEntry}`);
729
+ if (data) {
730
+ console.log(" Data:", data);
731
+ }
732
+ }
733
+ /**
734
+ * Start timing an operation
735
+ */
736
+ startTiming(label) {
737
+ if (!this.isDevelopment) return;
738
+ const perfNow = typeof performance !== "undefined" ? performance.now() : Date.now();
739
+ this.timings.set(label, perfNow);
740
+ }
741
+ /**
742
+ * End timing and log result
743
+ */
744
+ endTiming(label) {
745
+ if (!this.isDevelopment) return;
746
+ const start = this.timings.get(label);
747
+ if (!start) return;
748
+ const perfNow = typeof performance !== "undefined" ? performance.now() : Date.now();
749
+ const duration = perfNow - start;
750
+ this.log(`${label} took ${duration.toFixed(2)}ms`);
751
+ this.timings.delete(label);
752
+ }
753
+ /**
754
+ * Format transaction for display
755
+ */
756
+ formatTransaction(analysis) {
757
+ const lines = [
758
+ "\u{1F4CB} Transaction Analysis",
759
+ "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
760
+ `Instructions: ${analysis.instructions.length}`,
761
+ `Total Accounts: ${analysis.totalAccounts}`,
762
+ `Signers: ${analysis.signerCount}`,
763
+ `Estimated Size: ${analysis.estimatedSize} bytes`,
764
+ `Estimated Compute Units: ${analysis.estimatedComputeUnits.toLocaleString()}`,
765
+ `Estimated Fee: ${(Number(analysis.estimatedFee) / 1e9).toFixed(6)} SOL`,
766
+ ""
767
+ ];
768
+ lines.push("Instructions:");
769
+ for (const instr of analysis.instructions) {
770
+ lines.push(` ${instr.index + 1}. ${instr.humanReadable}`);
771
+ lines.push(` Program: ${instr.programId.slice(0, 8)}...`);
772
+ lines.push(` Accounts: ${instr.accountCount}, Data: ${instr.dataSize} bytes`);
773
+ }
774
+ if (analysis.warnings.length > 0) {
775
+ lines.push("");
776
+ lines.push("\u26A0\uFE0F Warnings:");
777
+ for (const warning of analysis.warnings) {
778
+ lines.push(` - ${warning}`);
779
+ }
780
+ }
781
+ lines.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
782
+ return lines.join("\n");
783
+ }
784
+ /**
785
+ * Export debug logs
786
+ */
787
+ exportLogs() {
788
+ return [...this.logs];
789
+ }
790
+ /**
791
+ * Clear debug logs
792
+ */
793
+ clearLogs() {
794
+ this.logs = [];
795
+ this.timings.clear();
796
+ }
797
+ };
798
+ function validateInstruction(instruction) {
799
+ const inst = instruction;
800
+ if (!inst.programAddress) {
801
+ throw new Error("Invalid instruction format");
802
+ }
803
+ }
804
+ var InstructionBuilder = class {
805
+ rpcClient;
806
+ config;
807
+ devTools;
808
+ debugMode = false;
809
+ constructor(config) {
810
+ this.config = config;
811
+ this.rpcClient = new RpcClient({
812
+ endpoint: config.rpcEndpoint ?? "https://api.devnet.solana.com",
813
+ wsEndpoint: config.wsEndpoint,
814
+ commitment: config.commitment ?? "confirmed"
815
+ });
816
+ this.devTools = DevTools.getInstance(config);
817
+ }
818
+ /**
819
+ * Execute a single instruction with unified error handling and transaction patterns
820
+ */
821
+ async execute(instructionName, instructionGetter, signers, options) {
822
+ const context = createErrorContext(
823
+ "execute",
824
+ instructionName,
825
+ signers.map((s) => ({ address: s.address, name: "signer" })),
826
+ { programId: this.config.programId }
827
+ );
828
+ try {
829
+ if (this.devTools.isDevMode()) {
830
+ this.devTools.startTiming(instructionName);
831
+ }
832
+ const instruction = await Promise.resolve(instructionGetter());
833
+ validateInstruction(instruction);
834
+ if (this.debugMode || this.devTools.isDevMode()) {
835
+ const analysis = this.devTools.analyzeTransaction([instruction]);
836
+ console.log(this.devTools.formatTransaction(analysis));
837
+ this.debugMode = false;
838
+ }
839
+ if (options?.simulate) {
840
+ return await this.simulateInstruction(instruction, signers);
841
+ }
842
+ const latestBlockhashResult = await this.rpcClient.getLatestBlockhash();
843
+ const latestBlockhash = {
844
+ blockhash: latestBlockhashResult.blockhash,
845
+ lastValidBlockHeight: latestBlockhashResult.lastValidBlockHeight
846
+ };
847
+ const transactionMessage = pipe(
848
+ createTransactionMessage({ version: 0 }),
849
+ (tx) => setTransactionMessageFeePayerSigner(signers[0], tx),
850
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
851
+ (tx) => appendTransactionMessageInstructions([instruction], tx)
852
+ );
853
+ const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
854
+ const signatureResult = await this.sendAndConfirm(
855
+ signedTransaction,
856
+ options?.skipPreflight ?? false,
857
+ options?.maxRetries ?? 30
858
+ );
859
+ if (typeof signatureResult !== "string") {
860
+ throw new Error("Transaction signature is not a string");
861
+ }
862
+ const signature = signatureResult;
863
+ if (options?.returnDetails) {
864
+ const cluster = this.config.cluster ?? "devnet";
865
+ const result = createTransactionResult(signature, cluster, this.config.commitment ?? "confirmed");
866
+ if (this.devTools.isDevMode()) {
867
+ this.devTools.endTiming(instructionName);
868
+ }
869
+ return result;
870
+ }
871
+ if (this.devTools.isDevMode()) {
872
+ this.devTools.endTiming(instructionName);
873
+ }
874
+ return signature;
875
+ } catch (error) {
876
+ logEnhancedError(error, context);
877
+ throw error;
878
+ }
879
+ }
880
+ /**
881
+ * Execute multiple instructions in a single transaction
882
+ */
883
+ async executeBatch(batchName, instructionGetters, signers, options) {
884
+ const context = createErrorContext(
885
+ "executeBatch",
886
+ batchName,
887
+ signers.map((s) => ({ address: s.address, name: "signer" })),
888
+ { programId: this.config.programId, instructionCount: instructionGetters.length }
889
+ );
890
+ try {
891
+ const instructions = await Promise.all(
892
+ instructionGetters.map(async (getter, i) => {
893
+ const instruction = await Promise.resolve(getter());
894
+ try {
895
+ validateInstruction(instruction);
896
+ return instruction;
897
+ } catch (error) {
898
+ throw new Error(`Instruction ${i} in ${batchName}: ${error.message}`);
899
+ }
900
+ })
901
+ );
902
+ const estimatedSize = this.estimateTransactionSize(instructions);
903
+ if (estimatedSize > 1232) {
904
+ throw new Error(`Transaction too large: ${estimatedSize} bytes (max: 1232)`);
905
+ }
906
+ if (options?.simulate) {
907
+ return await this.simulateBatch(instructions, signers);
908
+ }
909
+ const latestBlockhashResult = await this.rpcClient.getLatestBlockhash();
910
+ const latestBlockhash = {
911
+ blockhash: latestBlockhashResult.blockhash,
912
+ lastValidBlockHeight: latestBlockhashResult.lastValidBlockHeight
913
+ };
914
+ const transactionMessage = pipe(
915
+ createTransactionMessage({ version: 0 }),
916
+ (tx) => setTransactionMessageFeePayerSigner(signers[0], tx),
917
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
918
+ (tx) => appendTransactionMessageInstructions(instructions, tx)
919
+ );
920
+ const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
921
+ const signatureResult = await this.sendAndConfirm(
922
+ signedTransaction,
923
+ options?.skipPreflight ?? false
924
+ );
925
+ if (typeof signatureResult !== "string") {
926
+ throw new Error("Transaction signature is not a string");
927
+ }
928
+ const signature = signatureResult;
929
+ if (options?.returnDetails) {
930
+ const cluster = this.config.cluster ?? "devnet";
931
+ const result = createTransactionResult(signature, cluster, this.config.commitment ?? "confirmed");
932
+ if (this.devTools.isDevMode()) {
933
+ this.devTools.endTiming(batchName);
934
+ }
935
+ return result;
936
+ }
937
+ if (this.devTools.isDevMode()) {
938
+ this.devTools.endTiming(batchName);
939
+ }
940
+ return signature;
941
+ } catch (error) {
942
+ logEnhancedError(error, context);
943
+ throw error;
944
+ }
945
+ }
946
+ /**
947
+ * Get and decode account data with unified error handling
948
+ */
949
+ async getAccount(address2, decoderImportName) {
950
+ try {
951
+ const accountInfo = await this.rpcClient.getAccountInfo(address2, {
952
+ commitment: this.config.commitment
953
+ });
954
+ if (!accountInfo) return null;
955
+ const generated = await import('./generated-QJREJQ2C.js');
956
+ const decoderGetter = generated[decoderImportName];
957
+ const decoder = decoderGetter();
958
+ const rawData = this.extractRawData(accountInfo.data);
959
+ return decoder.decode(rawData);
960
+ } catch (error) {
961
+ console.warn(`Failed to fetch account ${address2}:`, error);
962
+ return null;
963
+ }
964
+ }
965
+ /**
966
+ * Get multiple accounts with unified pattern
967
+ */
968
+ async getAccounts(addresses, decoderImportName) {
969
+ try {
970
+ const accounts = await this.rpcClient.getMultipleAccounts(addresses, {
971
+ commitment: this.config.commitment
972
+ });
973
+ const generated = await import('./generated-QJREJQ2C.js');
974
+ const decoderGetter = generated[decoderImportName];
975
+ const decoder = decoderGetter();
976
+ return accounts.map((accountInfo) => {
977
+ if (!accountInfo) return null;
978
+ try {
979
+ const rawData = this.extractRawData(accountInfo.data);
980
+ return decoder.decode(rawData);
981
+ } catch {
982
+ return null;
983
+ }
984
+ });
985
+ } catch (error) {
986
+ console.warn("Failed to fetch multiple accounts:", error);
987
+ return addresses.map(() => null);
988
+ }
989
+ }
990
+ /**
991
+ * Get program accounts with filters
992
+ */
993
+ async getProgramAccounts(decoderImportName, filters) {
994
+ try {
995
+ const convertedFilters = filters?.map((filter) => {
996
+ if ("dataSize" in filter) {
997
+ return { dataSize: filter.dataSize };
998
+ } else {
999
+ const encoding = filter.memcmp.encoding ?? "base58";
1000
+ if (encoding === "base64") {
1001
+ return {
1002
+ memcmp: {
1003
+ offset: filter.memcmp.offset,
1004
+ bytes: filter.memcmp.bytes,
1005
+ encoding: "base64"
1006
+ }
1007
+ };
1008
+ } else {
1009
+ return {
1010
+ memcmp: {
1011
+ offset: filter.memcmp.offset,
1012
+ bytes: filter.memcmp.bytes,
1013
+ encoding: "base58"
1014
+ }
1015
+ };
1016
+ }
1017
+ }
1018
+ });
1019
+ const accounts = await this.rpcClient.getProgramAccounts(this.config.programId, {
1020
+ commitment: this.config.commitment,
1021
+ filters: convertedFilters ?? []
1022
+ });
1023
+ const generated = await import('./generated-QJREJQ2C.js');
1024
+ const decoderGetter = generated[decoderImportName];
1025
+ const decoder = decoderGetter();
1026
+ const decodedAccounts = [];
1027
+ for (const { pubkey, account } of accounts) {
1028
+ try {
1029
+ const rawData = this.extractRawData(account.data);
1030
+ const decodedData = decoder.decode(rawData);
1031
+ decodedAccounts.push({ address: pubkey, data: decodedData });
1032
+ } catch {
1033
+ }
1034
+ }
1035
+ return decodedAccounts;
1036
+ } catch (error) {
1037
+ console.error("Failed to get program accounts:", error);
1038
+ return [];
1039
+ }
1040
+ }
1041
+ /**
1042
+ * Enable debug mode for next transaction
1043
+ */
1044
+ enableDebug() {
1045
+ this.debugMode = true;
1046
+ return this;
1047
+ }
1048
+ /**
1049
+ * Debug transaction - analyze without executing
1050
+ */
1051
+ async debug(instructionName, instructionGetters) {
1052
+ this.devTools.log(`Debugging ${instructionName}`);
1053
+ const instructions = await Promise.all(
1054
+ instructionGetters.map(async (getter) => {
1055
+ const instruction = await Promise.resolve(getter());
1056
+ validateInstruction(instruction);
1057
+ return instruction;
1058
+ })
1059
+ );
1060
+ const analysis = this.devTools.analyzeTransaction(instructions);
1061
+ console.log(this.devTools.formatTransaction(analysis));
1062
+ return analysis;
1063
+ }
1064
+ /**
1065
+ * Get human-readable explanation of transaction
1066
+ */
1067
+ async explain(instructionName, instructionGetters) {
1068
+ const analysis = await this.debug(instructionName, instructionGetters);
1069
+ const lines = [
1070
+ `\u{1F50D} Transaction: ${instructionName}`,
1071
+ "",
1072
+ "This transaction will:",
1073
+ ...analysis.instructions.map((instr, i) => ` ${i + 1}. ${instr.humanReadable}`),
1074
+ "",
1075
+ `Cost: ~${(Number(analysis.estimatedFee) / 1e9).toFixed(6)} SOL`,
1076
+ `Size: ${analysis.estimatedSize} bytes`,
1077
+ `Compute: ${analysis.estimatedComputeUnits.toLocaleString()} units`
1078
+ ];
1079
+ if (analysis.warnings.length > 0) {
1080
+ lines.push("", "\u26A0\uFE0F Warnings:");
1081
+ lines.push(...analysis.warnings.map((w) => ` - ${w}`));
1082
+ }
1083
+ return lines.join("\n");
1084
+ }
1085
+ /**
1086
+ * Estimate transaction cost
1087
+ */
1088
+ async estimateCost(instructionGetters) {
1089
+ try {
1090
+ const instructions = await Promise.all(
1091
+ instructionGetters.map(async (getter) => {
1092
+ const instruction = await Promise.resolve(getter());
1093
+ validateInstruction(instruction);
1094
+ return instruction;
1095
+ })
1096
+ );
1097
+ const latestBlockhashResult = await this.rpcClient.getLatestBlockhash();
1098
+ const latestBlockhash = {
1099
+ blockhash: latestBlockhashResult.blockhash,
1100
+ lastValidBlockHeight: latestBlockhashResult.lastValidBlockHeight
1101
+ };
1102
+ const transactionMessage = pipe(
1103
+ createTransactionMessage({ version: 0 }),
1104
+ (tx) => setTransactionMessageFeePayer(this.config.defaultFeePayer, tx),
1105
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
1106
+ (tx) => appendTransactionMessageInstructions(instructions, tx)
1107
+ );
1108
+ const compiledMessage = compileTransactionMessage(transactionMessage);
1109
+ const encodedMessage = Buffer.from(compiledMessage).toString("base64");
1110
+ const fee = await this.rpcClient.getFeeForMessage(encodedMessage);
1111
+ return BigInt(fee ?? 0);
1112
+ } catch {
1113
+ const baseFee = 5000n;
1114
+ const perInstructionFee = 1000n;
1115
+ return baseFee + BigInt(instructionGetters.length) * perInstructionFee;
1116
+ }
1117
+ }
1118
+ // Private helper methods
1119
+ async sendAndConfirm(signedTransaction, skipPreflight, maxRetries = 30) {
1120
+ const wireTransaction = getBase64EncodedWireTransaction(signedTransaction);
1121
+ const signature = await this.rpcClient.sendTransaction(wireTransaction, {
1122
+ skipPreflight,
1123
+ preflightCommitment: this.config.commitment
1124
+ });
1125
+ console.log("\u{1F50D} Transaction sent, signature:", signature);
1126
+ console.log("\u{1F50D} Signature length:", signature.length);
1127
+ console.log("\u{1F50D} Signature type:", typeof signature);
1128
+ let confirmed = false;
1129
+ let attempts = 0;
1130
+ let currentDelay = 1e3;
1131
+ const maxConfirmationTime = 3e4;
1132
+ const startTime = Date.now();
1133
+ while (!confirmed && attempts < maxRetries && Date.now() - startTime < maxConfirmationTime) {
1134
+ try {
1135
+ console.log(`\u{1F50D} Confirmation attempt ${attempts + 1}/${maxRetries}`);
1136
+ const statuses = await this.rpcClient.getSignatureStatuses([signature]);
1137
+ if (statuses[0]) {
1138
+ console.log("\u{1F50D} Status found:", statuses[0]);
1139
+ if (statuses[0].err) {
1140
+ throw new Error(`Transaction failed: ${JSON.stringify(statuses[0].err, (_, v) => typeof v === "bigint" ? v.toString() : v)}`);
1141
+ }
1142
+ const confirmationStatus = statuses[0].confirmationStatus;
1143
+ if (confirmationStatus === this.config.commitment || this.config.commitment === "confirmed" && confirmationStatus === "finalized") {
1144
+ confirmed = true;
1145
+ console.log("\u2705 Transaction confirmed via status check");
1146
+ break;
1147
+ }
1148
+ } else {
1149
+ console.log("\u{1F50D} No status found, trying transaction details...");
1150
+ try {
1151
+ const { createSolanaRpc: createSolanaRpc2 } = await import('@solana/kit');
1152
+ const directRpc = createSolanaRpc2(this.config.rpcEndpoint ?? "https://api.devnet.solana.com");
1153
+ const transaction = await directRpc.getTransaction(signature, {
1154
+ commitment: this.config.commitment ?? "confirmed",
1155
+ encoding: "json",
1156
+ maxSupportedTransactionVersion: 0
1157
+ }).send();
1158
+ if (transaction && transaction.meta) {
1159
+ if (transaction.meta.err) {
1160
+ throw new Error(`Transaction failed: ${JSON.stringify(transaction.meta.err, (_, v) => typeof v === "bigint" ? v.toString() : v)}`);
1161
+ }
1162
+ confirmed = true;
1163
+ console.log("\u2705 Transaction confirmed via direct lookup");
1164
+ break;
1165
+ }
1166
+ } catch {
1167
+ console.log("\u{1F50D} Transaction details not yet available");
1168
+ }
1169
+ }
1170
+ attempts++;
1171
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1172
+ currentDelay = Math.min(currentDelay * 1.5, 5e3);
1173
+ } catch (error) {
1174
+ if (error instanceof Error && error.message.includes("Transaction failed")) {
1175
+ throw error;
1176
+ }
1177
+ console.log(`\u{1F50D} Confirmation attempt failed:`, error.message);
1178
+ attempts++;
1179
+ await new Promise((resolve) => setTimeout(resolve, currentDelay * 2));
1180
+ }
1181
+ }
1182
+ if (!confirmed) {
1183
+ console.log("\u{1F50D} Final confirmation attempt via transaction lookup...");
1184
+ try {
1185
+ const { createSolanaRpc: createSolanaRpc2 } = await import('@solana/kit');
1186
+ const directRpc = createSolanaRpc2(this.config.rpcEndpoint ?? "https://api.devnet.solana.com");
1187
+ const transaction = await directRpc.getTransaction(signature, {
1188
+ commitment: this.config.commitment ?? "confirmed",
1189
+ encoding: "json",
1190
+ maxSupportedTransactionVersion: 0
1191
+ }).send();
1192
+ if (transaction && transaction.meta) {
1193
+ if (transaction.meta.err) {
1194
+ throw new Error(`Transaction failed: ${JSON.stringify(transaction.meta.err, (_, v) => typeof v === "bigint" ? v.toString() : v)}`);
1195
+ }
1196
+ console.log("\u2705 Transaction confirmed on final check - returning success");
1197
+ return signature;
1198
+ }
1199
+ } catch (finalError) {
1200
+ console.log("\u{1F50D} Final check failed:", finalError.message);
1201
+ }
1202
+ console.log("\u26A0\uFE0F Transaction confirmation timed out, but transaction was sent");
1203
+ console.log(` Check status at: https://explorer.solana.com/tx/${signature}?cluster=${this.config.cluster || "devnet"}`);
1204
+ return signature;
1205
+ }
1206
+ return signature;
1207
+ }
1208
+ async simulateInstruction(instruction, signers) {
1209
+ const latestBlockhashResult = await this.rpcClient.getLatestBlockhash();
1210
+ const latestBlockhash = {
1211
+ blockhash: latestBlockhashResult.blockhash,
1212
+ lastValidBlockHeight: latestBlockhashResult.lastValidBlockHeight
1213
+ };
1214
+ const transactionMessage = pipe(
1215
+ createTransactionMessage({ version: 0 }),
1216
+ (tx) => setTransactionMessageFeePayerSigner(signers[0], tx),
1217
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
1218
+ (tx) => appendTransactionMessageInstructions([instruction], tx)
1219
+ );
1220
+ const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
1221
+ const wireTransaction = getBase64EncodedWireTransaction(signedTransaction);
1222
+ return this.rpcClient.simulateTransaction(wireTransaction, {
1223
+ commitment: this.config.commitment,
1224
+ replaceRecentBlockhash: true
1225
+ });
1226
+ }
1227
+ async simulateBatch(instructions, signers) {
1228
+ const latestBlockhashResult = await this.rpcClient.getLatestBlockhash();
1229
+ const latestBlockhash = {
1230
+ blockhash: latestBlockhashResult.blockhash,
1231
+ lastValidBlockHeight: latestBlockhashResult.lastValidBlockHeight
1232
+ };
1233
+ const transactionMessage = pipe(
1234
+ createTransactionMessage({ version: 0 }),
1235
+ (tx) => setTransactionMessageFeePayerSigner(signers[0], tx),
1236
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
1237
+ (tx) => appendTransactionMessageInstructions(instructions, tx)
1238
+ );
1239
+ const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
1240
+ const wireTransaction = getBase64EncodedWireTransaction(signedTransaction);
1241
+ return this.rpcClient.simulateTransaction(wireTransaction, {
1242
+ commitment: this.config.commitment,
1243
+ replaceRecentBlockhash: true
1244
+ });
1245
+ }
1246
+ estimateTransactionSize(instructions) {
1247
+ let totalSize = 64;
1248
+ for (const instruction of instructions) {
1249
+ totalSize += 32;
1250
+ totalSize += (instruction.accounts?.length ?? 0) * 32;
1251
+ totalSize += instruction.data.length;
1252
+ }
1253
+ return totalSize;
1254
+ }
1255
+ extractRawData(data) {
1256
+ if (Buffer.isBuffer(data) || data instanceof Uint8Array) {
1257
+ return new Uint8Array(data);
1258
+ }
1259
+ if (typeof data === "object" && data !== null && "data" in data) {
1260
+ return Buffer.from(data.data, "base64");
1261
+ }
1262
+ if (typeof data === "string") {
1263
+ return Buffer.from(data, "base64");
1264
+ }
1265
+ throw new Error("Invalid account data format");
1266
+ }
1267
+ // =====================================================
1268
+ // H2A PROTOCOL INSTRUCTION METHODS
1269
+ // =====================================================
1270
+ /**
1271
+ * Create a communication session instruction
1272
+ */
1273
+ async createCommunicationSession(_params) {
1274
+ return {
1275
+ programAddress: this.config.programId,
1276
+ accounts: [],
1277
+ data: new Uint8Array(0)
1278
+ // Placeholder - would contain serialized instruction data
1279
+ };
1280
+ }
1281
+ /**
1282
+ * Send a communication message instruction
1283
+ */
1284
+ async sendCommunicationMessage(_sessionAddress, _params) {
1285
+ return {
1286
+ programAddress: this.config.programId,
1287
+ accounts: [],
1288
+ data: new Uint8Array(0)
1289
+ // Placeholder - would contain serialized instruction data
1290
+ };
1291
+ }
1292
+ /**
1293
+ * Update participant status instruction
1294
+ */
1295
+ async updateParticipantStatus(_params) {
1296
+ return {
1297
+ programAddress: this.config.programId,
1298
+ accounts: [],
1299
+ data: new Uint8Array(0)
1300
+ // Placeholder - would contain serialized instruction data
1301
+ };
1302
+ }
1303
+ };
1304
+ var DEFAULT_TTLS = {
1305
+ processed: 500,
1306
+ // 500ms - very volatile
1307
+ confirmed: 2e3,
1308
+ // 2s - less volatile
1309
+ finalized: 3e4
1310
+ // 30s - stable
1311
+ };
1312
+ var CacheManager = class {
1313
+ accountCache;
1314
+ pdaCache;
1315
+ config;
1316
+ ttls;
1317
+ constructor(config = {}) {
1318
+ this.config = {
1319
+ enabled: config.enabled ?? false,
1320
+ maxSize: config.maxSize ?? 1e3,
1321
+ ttlOverrides: config.ttlOverrides ?? {}
1322
+ };
1323
+ this.ttls = {
1324
+ processed: config.ttlOverrides?.processed ?? DEFAULT_TTLS.processed,
1325
+ confirmed: config.ttlOverrides?.confirmed ?? DEFAULT_TTLS.confirmed,
1326
+ finalized: config.ttlOverrides?.finalized ?? DEFAULT_TTLS.finalized
1327
+ };
1328
+ this.accountCache = new LRUCache({
1329
+ max: this.config.maxSize,
1330
+ ttl: DEFAULT_TTLS.finalized
1331
+ // Default TTL (overridden per entry)
1332
+ });
1333
+ this.pdaCache = new LRUCache({
1334
+ max: this.config.maxSize
1335
+ });
1336
+ }
1337
+ /**
1338
+ * Check if caching is enabled
1339
+ */
1340
+ isEnabled() {
1341
+ return this.config.enabled;
1342
+ }
1343
+ /**
1344
+ * Get cached account data
1345
+ *
1346
+ * @param address - Account address
1347
+ * @param commitment - Commitment level
1348
+ * @param currentSlot - Current blockchain slot (for staleness check)
1349
+ * @returns Cached data or undefined
1350
+ */
1351
+ getAccount(address2, commitment, currentSlot) {
1352
+ if (!this.config.enabled) return void 0;
1353
+ const key = `${address2}:${commitment}`;
1354
+ const entry = this.accountCache.get(key);
1355
+ if (!entry) return void 0;
1356
+ if (currentSlot !== void 0 && entry.slot < currentSlot) {
1357
+ this.accountCache.delete(key);
1358
+ return void 0;
1359
+ }
1360
+ return entry.data;
1361
+ }
1362
+ /**
1363
+ * Cache account data
1364
+ *
1365
+ * @param address - Account address
1366
+ * @param data - Account data to cache
1367
+ * @param commitment - Commitment level
1368
+ * @param slot - Blockchain slot when data was fetched
1369
+ */
1370
+ setAccount(address2, data, commitment, slot) {
1371
+ if (!this.config.enabled) return;
1372
+ const key = `${address2}:${commitment}`;
1373
+ const entry = {
1374
+ data,
1375
+ slot,
1376
+ commitment,
1377
+ timestamp: Date.now()
1378
+ };
1379
+ this.accountCache.set(key, entry, {
1380
+ ttl: this.ttls[commitment]
1381
+ });
1382
+ }
1383
+ /**
1384
+ * Get cached PDA
1385
+ *
1386
+ * PDAs are cached indefinitely as they're deterministic.
1387
+ *
1388
+ * @param seeds - Serialized seed components
1389
+ * @returns Cached PDA or undefined
1390
+ */
1391
+ getPDA(seeds) {
1392
+ if (!this.config.enabled) return void 0;
1393
+ return this.pdaCache.get(seeds);
1394
+ }
1395
+ /**
1396
+ * Cache PDA derivation
1397
+ *
1398
+ * @param seeds - Serialized seed components (use JSON.stringify for consistency)
1399
+ * @param pda - Derived PDA address
1400
+ */
1401
+ setPDA(seeds, pda) {
1402
+ if (!this.config.enabled) return;
1403
+ this.pdaCache.set(seeds, pda);
1404
+ }
1405
+ /**
1406
+ * Invalidate account cache entry
1407
+ *
1408
+ * @param address - Account address to invalidate
1409
+ * @param commitment - Optional commitment level (invalidates all if not specified)
1410
+ */
1411
+ invalidateAccount(address2, commitment) {
1412
+ if (!this.config.enabled) return;
1413
+ if (commitment) {
1414
+ this.accountCache.delete(`${address2}:${commitment}`);
1415
+ } else {
1416
+ ["processed", "confirmed", "finalized"].forEach((c) => {
1417
+ this.accountCache.delete(`${address2}:${c}`);
1418
+ });
1419
+ }
1420
+ }
1421
+ /**
1422
+ * Clear all caches
1423
+ */
1424
+ clear() {
1425
+ this.accountCache.clear();
1426
+ this.pdaCache.clear();
1427
+ }
1428
+ /**
1429
+ * Get cache statistics
1430
+ *
1431
+ * @returns Cache size and hit/miss stats
1432
+ */
1433
+ getStats() {
1434
+ return {
1435
+ accountCache: {
1436
+ size: this.accountCache.size,
1437
+ max: this.config.maxSize
1438
+ },
1439
+ pdaCache: {
1440
+ size: this.pdaCache.size,
1441
+ max: this.config.maxSize
1442
+ }
1443
+ };
1444
+ }
1445
+ };
1446
+
1447
+ // src/core/BaseModule.ts
1448
+ var BaseModule = class {
1449
+ builder;
1450
+ config;
1451
+ logger;
1452
+ cacheManager;
1453
+ _debugMode = false;
1454
+ constructor(config) {
1455
+ this.config = config;
1456
+ this.builder = new InstructionBuilder(config);
1457
+ this.cacheManager = new CacheManager(config.cache);
1458
+ this.logger = config.logger;
1459
+ }
1460
+ /**
1461
+ * Enable debug mode for next operation
1462
+ */
1463
+ debug() {
1464
+ this._debugMode = true;
1465
+ this.builder.enableDebug();
1466
+ return this;
1467
+ }
1468
+ /**
1469
+ * Execute a single instruction
1470
+ */
1471
+ async execute(instructionName, instructionGetter, signers) {
1472
+ return this.builder.execute(
1473
+ instructionName,
1474
+ instructionGetter,
1475
+ signers
1476
+ );
1477
+ }
1478
+ /**
1479
+ * Execute a single instruction with detailed result
1480
+ */
1481
+ async executeWithDetails(instructionName, instructionGetter, signers) {
1482
+ return this.builder.execute(
1483
+ instructionName,
1484
+ instructionGetter,
1485
+ signers,
1486
+ { returnDetails: true }
1487
+ );
1488
+ }
1489
+ /**
1490
+ * Execute multiple instructions in a batch
1491
+ */
1492
+ async executeBatch(batchName, instructionGetters, signers) {
1493
+ return this.builder.executeBatch(
1494
+ batchName,
1495
+ instructionGetters.map((getter) => () => Promise.resolve(getter())),
1496
+ signers
1497
+ );
1498
+ }
1499
+ /**
1500
+ * Simulate an instruction
1501
+ */
1502
+ async simulate(instructionName, instructionGetter, signers) {
1503
+ return this.builder.execute(
1504
+ instructionName,
1505
+ () => Promise.resolve(instructionGetter()),
1506
+ signers,
1507
+ { simulate: true }
1508
+ );
1509
+ }
1510
+ /**
1511
+ * Simulate an instruction (public accessor)
1512
+ */
1513
+ async simulateInstruction(instructionName, instructionGetter, signers) {
1514
+ return this.simulate(instructionName, instructionGetter, signers);
1515
+ }
1516
+ /**
1517
+ * Estimate transaction cost
1518
+ */
1519
+ async estimateCost(instructionGetters) {
1520
+ return this.builder.estimateCost(instructionGetters);
1521
+ }
1522
+ /**
1523
+ * Get cost estimation for an instruction
1524
+ */
1525
+ async getCost(instructionName, instructionGetter) {
1526
+ return this.builder.estimateCost([instructionGetter]);
1527
+ }
1528
+ /**
1529
+ * Get human-readable explanation
1530
+ */
1531
+ async explain(instructionName, instructionGetter) {
1532
+ return this.builder.explain(instructionName, [instructionGetter]);
1533
+ }
1534
+ /**
1535
+ * Debug analyze without executing
1536
+ */
1537
+ async analyze(instructionName, instructionGetter) {
1538
+ return this.builder.debug(instructionName, [instructionGetter]);
1539
+ }
1540
+ /**
1541
+ * Get decoded account (with optional caching)
1542
+ */
1543
+ async getAccount(address2, decoderImportName) {
1544
+ if (this.cacheManager.isEnabled()) {
1545
+ const cached = this.cacheManager.getAccount(address2, this.commitment);
1546
+ if (cached !== void 0) {
1547
+ this.logger?.info(`[Cache HIT] ${address2}`);
1548
+ return cached;
1549
+ }
1550
+ }
1551
+ const account = await this.builder.getAccount(address2, decoderImportName);
1552
+ if (this.cacheManager.isEnabled() && account !== null) {
1553
+ const slot = 0;
1554
+ this.cacheManager.setAccount(address2, account, this.commitment, slot);
1555
+ this.logger?.info(`[Cache SET] ${address2}`);
1556
+ }
1557
+ return account;
1558
+ }
1559
+ /**
1560
+ * Get multiple decoded accounts (with optional caching)
1561
+ */
1562
+ async getAccounts(addresses, decoderImportName) {
1563
+ if (!this.cacheManager.isEnabled()) {
1564
+ return this.builder.getAccounts(addresses, decoderImportName);
1565
+ }
1566
+ const results = new Array(addresses.length);
1567
+ const uncachedIndices = [];
1568
+ const uncachedAddresses = [];
1569
+ for (let i = 0; i < addresses.length; i++) {
1570
+ const cached = this.cacheManager.getAccount(addresses[i], this.commitment);
1571
+ if (cached !== void 0) {
1572
+ results[i] = cached;
1573
+ this.logger?.info(`[Cache HIT] ${addresses[i]}`);
1574
+ } else {
1575
+ uncachedIndices.push(i);
1576
+ uncachedAddresses.push(addresses[i]);
1577
+ }
1578
+ }
1579
+ if (uncachedAddresses.length > 0) {
1580
+ this.logger?.info(`[Cache MISS] Fetching ${uncachedAddresses.length}/${addresses.length} accounts`);
1581
+ const fetched = await this.builder.getAccounts(uncachedAddresses, decoderImportName);
1582
+ const slot = 0;
1583
+ for (let i = 0; i < fetched.length; i++) {
1584
+ const originalIndex = uncachedIndices[i];
1585
+ const account = fetched[i];
1586
+ results[originalIndex] = account;
1587
+ if (account !== null) {
1588
+ this.cacheManager.setAccount(uncachedAddresses[i], account, this.commitment, slot);
1589
+ }
1590
+ }
1591
+ }
1592
+ return results;
1593
+ }
1594
+ /**
1595
+ * Get program accounts
1596
+ */
1597
+ async getProgramAccounts(decoderImportName, filters) {
1598
+ return this.builder.getProgramAccounts(decoderImportName, filters);
1599
+ }
1600
+ /**
1601
+ * Get program ID
1602
+ */
1603
+ get programId() {
1604
+ return this.config.programId;
1605
+ }
1606
+ /**
1607
+ * Get program ID (public accessor)
1608
+ */
1609
+ getProgramId() {
1610
+ return this.config.programId;
1611
+ }
1612
+ /**
1613
+ * Get commitment level
1614
+ */
1615
+ get commitment() {
1616
+ return this.config.commitment ?? "confirmed";
1617
+ }
1618
+ /**
1619
+ * Get commitment level (public accessor)
1620
+ */
1621
+ getCommitment() {
1622
+ return this.config.commitment ?? "confirmed";
1623
+ }
1624
+ /**
1625
+ * Invalidate cache for specific account
1626
+ */
1627
+ invalidateCache(address2) {
1628
+ this.cacheManager.invalidateAccount(address2);
1629
+ this.logger?.info(`[Cache INVALIDATE] ${address2}`);
1630
+ }
1631
+ /**
1632
+ * Clear all caches
1633
+ */
1634
+ clearCache() {
1635
+ this.cacheManager.clear();
1636
+ this.logger?.info("[Cache CLEAR] All caches cleared");
1637
+ }
1638
+ /**
1639
+ * Get cache statistics
1640
+ */
1641
+ getCacheStats() {
1642
+ return this.cacheManager.getStats();
1643
+ }
1644
+ };
1645
+
1646
+ // src/utils/ipfs-utils.ts
1647
+ var DEFAULT_IPFS_CONFIG = {
1648
+ provider: {
1649
+ name: "pinata",
1650
+ endpoint: "https://api.pinata.cloud"
1651
+ },
1652
+ gateways: [
1653
+ "https://gateway.pinata.cloud",
1654
+ "https://ipfs.io",
1655
+ "https://cloudflare-ipfs.com",
1656
+ "https://gateway.ipfs.io"
1657
+ ],
1658
+ autoPinning: true,
1659
+ sizeThreshold: 800,
1660
+ // 800 bytes threshold to stay under Solana transaction limits
1661
+ maxRetries: 3,
1662
+ retryDelay: 1e3,
1663
+ enableCache: true,
1664
+ cacheTTL: 3e5
1665
+ // 5 minutes
1666
+ };
1667
+ var IPFSUtils = class {
1668
+ client;
1669
+ constructor(config) {
1670
+ this.client = new IPFSClient(config);
1671
+ }
1672
+ /**
1673
+ * Store agent metadata with automatic IPFS/inline decision
1674
+ */
1675
+ async storeAgentMetadata(metadata, options) {
1676
+ const metadataJson = JSON.stringify({
1677
+ ...metadata,
1678
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1679
+ version: "1.0.0"
1680
+ });
1681
+ return this.client.storeContent(metadataJson, "agent-metadata", {
1682
+ filename: `agent-${metadata.agentId ?? "metadata"}.json`,
1683
+ metadata: {
1684
+ type: "agent-metadata",
1685
+ agentId: metadata.agentId,
1686
+ name: metadata.name
1687
+ },
1688
+ contentType: "application/json",
1689
+ ...options
1690
+ });
1691
+ }
1692
+ /**
1693
+ * Store channel message content with automatic IPFS/inline decision
1694
+ */
1695
+ async storeChannelMessage(message, options) {
1696
+ const messageJson = JSON.stringify({
1697
+ ...message,
1698
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1699
+ version: "1.0.0"
1700
+ });
1701
+ return this.client.storeContent(messageJson, "channel-message", {
1702
+ filename: `message-${Date.now()}.json`,
1703
+ metadata: {
1704
+ type: "channel-message",
1705
+ channelId: message.channelId,
1706
+ messageType: message.messageType ?? 0
1707
+ },
1708
+ contentType: "application/json",
1709
+ ...options
1710
+ });
1711
+ }
1712
+ /**
1713
+ * Store file attachments on IPFS
1714
+ */
1715
+ async storeFileAttachment(fileContent, filename, contentType, options) {
1716
+ const content = typeof fileContent === "string" ? fileContent : new TextDecoder().decode(fileContent);
1717
+ return this.client.storeContent(content, "file-attachment", {
1718
+ filename,
1719
+ contentType,
1720
+ metadata: {
1721
+ type: "file-attachment",
1722
+ originalFilename: filename,
1723
+ mimeType: contentType
1724
+ },
1725
+ ...options
1726
+ });
1727
+ }
1728
+ /**
1729
+ * Retrieve and parse agent metadata
1730
+ */
1731
+ async retrieveAgentMetadata(uri) {
1732
+ const content = await this.client.retrieveContent(uri);
1733
+ const parsed = JSON.parse(content);
1734
+ if (typeof parsed !== "object" || parsed === null) {
1735
+ throw new Error("Retrieved agent metadata is not a valid object");
1736
+ }
1737
+ return parsed;
1738
+ }
1739
+ /**
1740
+ * Retrieve and parse channel message content
1741
+ */
1742
+ async retrieveChannelMessage(uri) {
1743
+ const content = await this.client.retrieveContent(uri);
1744
+ const parsed = JSON.parse(content);
1745
+ if (typeof parsed !== "object" || parsed === null) {
1746
+ throw new Error("Retrieved channel message is not a valid object");
1747
+ }
1748
+ return parsed;
1749
+ }
1750
+ /**
1751
+ * Batch upload multiple content items
1752
+ */
1753
+ async batchUpload(items) {
1754
+ const results = await Promise.allSettled(
1755
+ items.map(
1756
+ (item) => this.client.storeContent(item.content, item.type, {
1757
+ filename: item.filename,
1758
+ ...item.options
1759
+ })
1760
+ )
1761
+ );
1762
+ return results.map((result) => {
1763
+ if (result.status === "fulfilled") {
1764
+ return {
1765
+ success: true,
1766
+ data: result.value
1767
+ };
1768
+ } else {
1769
+ return {
1770
+ success: false,
1771
+ error: "UPLOAD_FAILED",
1772
+ message: result.reason instanceof Error ? result.reason.message : String(result.reason)
1773
+ };
1774
+ }
1775
+ });
1776
+ }
1777
+ /**
1778
+ * Pin existing content by hash
1779
+ */
1780
+ async pinContent(hash) {
1781
+ const result = await this.client.pin(hash);
1782
+ return {
1783
+ ...result,
1784
+ data: result.success
1785
+ };
1786
+ }
1787
+ /**
1788
+ * Check if a URI uses IPFS storage
1789
+ */
1790
+ isIPFSUri(uri) {
1791
+ return uri.startsWith("ipfs://");
1792
+ }
1793
+ /**
1794
+ * Extract IPFS hash from URI
1795
+ */
1796
+ extractIPFSHash(uri) {
1797
+ if (!this.isIPFSUri(uri)) {
1798
+ return null;
1799
+ }
1800
+ return uri.replace("ipfs://", "");
1801
+ }
1802
+ /**
1803
+ * Convert IPFS hash to gateway URLs
1804
+ */
1805
+ getGatewayUrls(hash, gateways) {
1806
+ const defaultGateways = gateways ?? DEFAULT_IPFS_CONFIG.gateways ?? [];
1807
+ return defaultGateways.map((gateway) => `${gateway}/ipfs/${hash}`);
1808
+ }
1809
+ /**
1810
+ * Validate IPFS hash format
1811
+ */
1812
+ isValidIPFSHash(hash) {
1813
+ if (hash.length < 44) return false;
1814
+ if (hash.startsWith("Qm") && hash.length === 46) {
1815
+ return /^Qm[A-Za-z0-9]{44}$/.test(hash);
1816
+ }
1817
+ if (hash.length > 46) {
1818
+ return /^[A-Za-z0-9]+$/.test(hash);
1819
+ }
1820
+ return false;
1821
+ }
1822
+ /**
1823
+ * Calculate content size to determine if IPFS should be used
1824
+ */
1825
+ shouldUseIPFS(content, threshold) {
1826
+ const size = new TextEncoder().encode(content).length;
1827
+ const sizeThreshold = threshold ?? DEFAULT_IPFS_CONFIG.sizeThreshold ?? 800;
1828
+ return size > sizeThreshold;
1829
+ }
1830
+ /**
1831
+ * Compress content before IPFS upload using modern compression APIs
1832
+ */
1833
+ async compressContent(content) {
1834
+ try {
1835
+ if (typeof CompressionStream !== "undefined") {
1836
+ const compressedStream = new CompressionStream("gzip");
1837
+ const writer = compressedStream.writable.getWriter();
1838
+ const reader = compressedStream.readable.getReader();
1839
+ const encoder = new TextEncoder();
1840
+ const input = encoder.encode(content);
1841
+ const writePromise = writer.write(input).then(() => writer.close());
1842
+ const chunks = [];
1843
+ const readCompressed = async () => {
1844
+ const result = await reader.read();
1845
+ const { done, value } = result;
1846
+ if (!done && value) {
1847
+ chunks.push(value);
1848
+ await readCompressed();
1849
+ }
1850
+ };
1851
+ await Promise.all([writePromise, readCompressed()]);
1852
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
1853
+ const compressedData = new Uint8Array(totalLength);
1854
+ let offset = 0;
1855
+ for (const chunk of chunks) {
1856
+ compressedData.set(chunk, offset);
1857
+ offset += chunk.length;
1858
+ }
1859
+ const compressed = Buffer.from(compressedData).toString("base64");
1860
+ return {
1861
+ compressed,
1862
+ algorithm: "gzip"
1863
+ };
1864
+ } else {
1865
+ console.warn("Compression not available in this environment, storing uncompressed");
1866
+ return {
1867
+ compressed: content,
1868
+ algorithm: "none"
1869
+ };
1870
+ }
1871
+ } catch (error) {
1872
+ console.warn("Compression failed, falling back to uncompressed:", error);
1873
+ return {
1874
+ compressed: content,
1875
+ algorithm: "none"
1876
+ };
1877
+ }
1878
+ }
1879
+ /**
1880
+ * Decompress content after IPFS retrieval using modern decompression APIs
1881
+ */
1882
+ async decompressContent(compressed, algorithm) {
1883
+ if (algorithm === "none") {
1884
+ return compressed;
1885
+ }
1886
+ try {
1887
+ if (algorithm === "gzip") {
1888
+ if (typeof DecompressionStream !== "undefined") {
1889
+ const decompressedStream = new DecompressionStream("gzip");
1890
+ const writer = decompressedStream.writable.getWriter();
1891
+ const reader = decompressedStream.readable.getReader();
1892
+ const compressedData = Buffer.from(compressed, "base64");
1893
+ const writePromise = writer.write(compressedData).then(() => writer.close());
1894
+ const chunks = [];
1895
+ const readDecompressed = async () => {
1896
+ const result = await reader.read();
1897
+ const { done, value } = result;
1898
+ if (!done && value) {
1899
+ chunks.push(value);
1900
+ await readDecompressed();
1901
+ }
1902
+ };
1903
+ await Promise.all([writePromise, readDecompressed()]);
1904
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
1905
+ const decompressedData = new Uint8Array(totalLength);
1906
+ let offset = 0;
1907
+ for (const chunk of chunks) {
1908
+ decompressedData.set(chunk, offset);
1909
+ offset += chunk.length;
1910
+ }
1911
+ const decoder = new TextDecoder();
1912
+ return decoder.decode(decompressedData);
1913
+ } else {
1914
+ console.warn("Decompression not available in this environment, returning compressed data");
1915
+ return compressed;
1916
+ }
1917
+ } else {
1918
+ console.warn(`Unknown compression algorithm: ${algorithm}`);
1919
+ return compressed;
1920
+ }
1921
+ } catch (error) {
1922
+ console.error("Decompression failed, returning compressed data:", error);
1923
+ return compressed;
1924
+ }
1925
+ }
1926
+ /**
1927
+ * Get client stats
1928
+ */
1929
+ getStats() {
1930
+ return {
1931
+ cacheStats: this.client.getCacheStats(),
1932
+ config: DEFAULT_IPFS_CONFIG
1933
+ };
1934
+ }
1935
+ /**
1936
+ * Clear client cache
1937
+ */
1938
+ clearCache() {
1939
+ this.client.clearCache();
1940
+ }
1941
+ };
1942
+ function createIPFSUtils(config) {
1943
+ const finalConfig = {
1944
+ ...DEFAULT_IPFS_CONFIG,
1945
+ ...config,
1946
+ provider: {
1947
+ ...DEFAULT_IPFS_CONFIG.provider,
1948
+ ...config?.provider
1949
+ }
1950
+ };
1951
+ return new IPFSUtils(finalConfig);
1952
+ }
1953
+ function determineStorageMethod(content, options) {
1954
+ if (options?.forceInline) return "inline";
1955
+ if (options?.forceIPFS) return "ipfs";
1956
+ const size = new TextEncoder().encode(content).length;
1957
+ const threshold = options?.sizeThreshold ?? DEFAULT_IPFS_CONFIG.sizeThreshold ?? 800;
1958
+ return size > threshold ? "ipfs" : "inline";
1959
+ }
1960
+ async function createMetadataUri(metadata, ipfsUtils, options) {
1961
+ const metadataJson = JSON.stringify(metadata);
1962
+ const storageMethod = determineStorageMethod(metadataJson, {
1963
+ forceIPFS: options?.forceIPFS
1964
+ });
1965
+ if (storageMethod === "inline" || !ipfsUtils) {
1966
+ const encoded = Buffer.from(metadataJson).toString("base64");
1967
+ return `data:application/json;base64,${encoded}`;
1968
+ } else {
1969
+ const result = await ipfsUtils.client.storeContent(
1970
+ metadataJson,
1971
+ options?.type ?? "custom",
1972
+ {
1973
+ filename: options?.filename,
1974
+ contentType: "application/json"
1975
+ }
1976
+ );
1977
+ return result.uri;
1978
+ }
1979
+ }
1980
+
1981
+ // src/core/modules/AgentModule.ts
1982
+ var AgentModule = class extends BaseModule {
1983
+ ipfsUtils = null;
1984
+ constructor(config) {
1985
+ super(config);
1986
+ if (config.ipfsConfig) {
1987
+ this.ipfsUtils = createIPFSUtils(config.ipfsConfig);
1988
+ }
1989
+ }
1990
+ /**
1991
+ * Register a new agent
1992
+ */
1993
+ async register(signer, params) {
1994
+ const pricingModel = params.pricingModel ?? 0 /* Fixed */;
1995
+ const registerGetter = async () => {
1996
+ const agentAccount = await this.deriveAgentPda(params.agentId, signer.address);
1997
+ const ix = await getRegisterAgentInstructionAsync({
1998
+ agentAccount,
1999
+ signer,
2000
+ systemProgram: this.systemProgramId,
2001
+ agentType: params.agentType,
2002
+ name: params.name,
2003
+ description: params.description,
2004
+ metadataUri: params.metadataUri,
2005
+ agentId: params.agentId,
2006
+ pricingModel
2007
+ });
2008
+ return ix;
2009
+ };
2010
+ const heapGetter = () => {
2011
+ const heapData = new Uint8Array(5);
2012
+ heapData[0] = 1;
2013
+ new DataView(heapData.buffer).setUint32(1, 256 * 1024, true);
2014
+ return {
2015
+ programAddress: "ComputeBudget111111111111111111111111111111",
2016
+ accounts: [],
2017
+ data: heapData
2018
+ };
2019
+ };
2020
+ this.debug();
2021
+ if (params.skipSimulation) {
2022
+ console.log("\u{1F680} SKIPPING SIMULATION - Sending transaction directly");
2023
+ return this.builder.executeBatch(
2024
+ "registerAgent",
2025
+ [heapGetter, registerGetter],
2026
+ [signer],
2027
+ { simulate: false, skipPreflight: true }
2028
+ );
2029
+ }
2030
+ return this.builder.executeBatch(
2031
+ "registerAgent",
2032
+ [heapGetter, registerGetter],
2033
+ [signer]
2034
+ );
2035
+ }
2036
+ // registerX402Agent method removed - use PayAI integration
2037
+ /**
2038
+ * Register a compressed agent (5000x cheaper)
2039
+ */
2040
+ async registerCompressed(signer, params) {
2041
+ const instructionGetter = async () => {
2042
+ const treeConfig = params.treeConfig || await this.deriveTreeConfigPda(signer.address);
2043
+ const result = await getRegisterAgentCompressedInstructionAsync({
2044
+ merkleTree: params.merkleTree,
2045
+ treeAuthority: treeConfig,
2046
+ // Map to correct instruction field (it's treeAuthority in IDL?)
2047
+ signer,
2048
+ systemProgram: this.systemProgramId,
2049
+ compressionProgram: this.compressionProgramId,
2050
+ agentType: params.agentType,
2051
+ name: params.name,
2052
+ description: params.description,
2053
+ metadataUri: params.metadataUri,
2054
+ agentId: params.agentId,
2055
+ pricingModel: params.pricingModel ?? 0 /* Fixed */,
2056
+ logWrapper: "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV"
2057
+ // Explicitly provide Noop program
2058
+ });
2059
+ return result;
2060
+ };
2061
+ return this.execute(
2062
+ "registerAgentCompressed",
2063
+ instructionGetter,
2064
+ [signer]
2065
+ );
2066
+ }
2067
+ /**
2068
+ * Update agent metadata
2069
+ */
2070
+ async update(signer, params) {
2071
+ const instructionGetter = () => {
2072
+ const result = getUpdateAgentInstruction({
2073
+ agentAccount: params.agentAddress,
2074
+ signer,
2075
+ metadataUri: params.metadataUri,
2076
+ agentType: params.agentType,
2077
+ agentId: params.agentId,
2078
+ name: params.name ?? null,
2079
+ description: params.description ?? null,
2080
+ pricingModel: params.pricingModel ?? 0 /* Fixed */
2081
+ });
2082
+ return result;
2083
+ };
2084
+ return this.execute(
2085
+ "updateAgent",
2086
+ instructionGetter,
2087
+ [signer]
2088
+ );
2089
+ }
2090
+ /**
2091
+ * Verify an agent
2092
+ */
2093
+ async verify(signer, params) {
2094
+ const instructionGetter = async () => {
2095
+ const result = await getVerifyAgentInstructionAsync({
2096
+ agent: params.agentAddress,
2097
+ verifier: signer,
2098
+ agentPubkey: params.agentPubkey,
2099
+ serviceEndpoint: params.serviceEndpoint,
2100
+ supportedCapabilities: params.supportedCapabilities,
2101
+ verifiedAt: params.verifiedAt
2102
+ });
2103
+ return result;
2104
+ };
2105
+ return this.execute(
2106
+ "verifyAgent",
2107
+ instructionGetter,
2108
+ [signer]
2109
+ );
2110
+ }
2111
+ /**
2112
+ * Deactivate an agent
2113
+ */
2114
+ async deactivate(signer, params) {
2115
+ const instructionGetter = () => {
2116
+ const result = getDeactivateAgentInstruction({
2117
+ agentAccount: params.agentAddress,
2118
+ signer,
2119
+ agentId: params.agentId
2120
+ });
2121
+ return result;
2122
+ };
2123
+ return this.execute(
2124
+ "deactivateAgent",
2125
+ instructionGetter,
2126
+ [signer]
2127
+ );
2128
+ }
2129
+ /**
2130
+ * Activate an agent
2131
+ */
2132
+ async activate(signer, params) {
2133
+ const instructionGetter = () => {
2134
+ const result = getActivateAgentInstruction({
2135
+ agentAccount: params.agentAddress,
2136
+ signer,
2137
+ agentId: params.agentId
2138
+ });
2139
+ return result;
2140
+ };
2141
+ return this.execute(
2142
+ "activateAgent",
2143
+ instructionGetter,
2144
+ [signer]
2145
+ );
2146
+ }
2147
+ /**
2148
+ * Get agent account
2149
+ */
2150
+ async getAgentAccount(address2) {
2151
+ return super.getAccount(address2, "getAgentDecoder");
2152
+ }
2153
+ /**
2154
+ * Get all agents
2155
+ */
2156
+ async getAllAgents() {
2157
+ return this.getProgramAccounts("getAgentDecoder");
2158
+ }
2159
+ /**
2160
+ * Get agents by type
2161
+ */
2162
+ async getAgentsByType(agentType) {
2163
+ const typeBytes = Buffer.alloc(1);
2164
+ typeBytes.writeUInt8(agentType, 0);
2165
+ const filters = [{
2166
+ memcmp: {
2167
+ offset: BigInt(8),
2168
+ // Skip discriminator
2169
+ bytes: typeBytes.toString("base64"),
2170
+ encoding: "base64"
2171
+ }
2172
+ }];
2173
+ return this.getProgramAccounts("getAgentDecoder", filters);
2174
+ }
2175
+ /**
2176
+ * Get user's agents
2177
+ */
2178
+ async getUserAgents(authority) {
2179
+ const filters = [{
2180
+ memcmp: {
2181
+ offset: BigInt(9),
2182
+ // Skip discriminator + type
2183
+ bytes: authority,
2184
+ encoding: "base58"
2185
+ }
2186
+ }];
2187
+ return this.getProgramAccounts("getAgentDecoder", filters);
2188
+ }
2189
+ /**
2190
+ * Batch get multiple agent accounts
2191
+ *
2192
+ * Uses efficient batching (100 accounts per RPC call) with optional caching.
2193
+ *
2194
+ * @param addresses - Agent addresses to fetch
2195
+ * @param onProgress - Optional progress callback
2196
+ * @returns Array of agent accounts (null for non-existent)
2197
+ *
2198
+ * @example
2199
+ * ```typescript
2200
+ * const agents = await client.agents.batchGetAgents(
2201
+ * ['agent1...', 'agent2...', 'agent3...'],
2202
+ * (completed, total) => console.log(`${completed}/${total}`)
2203
+ * )
2204
+ * ```
2205
+ */
2206
+ async batchGetAgents(addresses, onProgress) {
2207
+ return super.getAccounts(addresses, "getAgentDecoder");
2208
+ }
2209
+ /**
2210
+ * Batch get only existing agent accounts
2211
+ *
2212
+ * Filters out non-existent addresses.
2213
+ *
2214
+ * @param addresses - Agent addresses to fetch
2215
+ * @param onProgress - Optional progress callback
2216
+ * @returns Array of existing agents with their addresses
2217
+ *
2218
+ * @example
2219
+ * ```typescript
2220
+ * const existingAgents = await client.agents.batchGetExistingAgents(['addr1', 'addr2'])
2221
+ * // Returns: [{ address: 'addr1', account: Agent }, ...]
2222
+ * ```
2223
+ */
2224
+ async batchGetExistingAgents(addresses, onProgress) {
2225
+ const { batchGetExistingAccounts } = await import('./batch-operations-45CQFEID.js');
2226
+ return batchGetExistingAccounts(
2227
+ this.config.rpc,
2228
+ addresses,
2229
+ { onProgress }
2230
+ );
2231
+ }
2232
+ /**
2233
+ * Batch get and map agents to a simplified format
2234
+ *
2235
+ * Useful for creating agent summaries or lists.
2236
+ *
2237
+ * @param addresses - Agent addresses to fetch
2238
+ * @param mapper - Transform function
2239
+ * @returns Array of mapped results
2240
+ *
2241
+ * @example
2242
+ * ```typescript
2243
+ * const summaries = await client.agents.batchGetAndMapAgents(
2244
+ * addresses,
2245
+ * (agent, address) => agent ? {
2246
+ * address,
2247
+ * name: agent.name,
2248
+ * type: agent.agentType,
2249
+ * active: agent.isActive
2250
+ * } : null
2251
+ * )
2252
+ * ```
2253
+ */
2254
+ async batchGetAndMapAgents(addresses, mapper) {
2255
+ const { batchGetAndMap } = await import('./batch-operations-45CQFEID.js');
2256
+ return batchGetAndMap(
2257
+ this.config.rpc,
2258
+ addresses,
2259
+ mapper
2260
+ );
2261
+ }
2262
+ // Helper methods
2263
+ async deriveAgentPda(agentId, owner) {
2264
+ const { deriveAgentPda } = await import('./pda-4KP7CURF.js');
2265
+ const [address2] = await deriveAgentPda({ programAddress: this.programId, owner, agentId });
2266
+ return address2;
2267
+ }
2268
+ async deriveUserRegistryPda(owner) {
2269
+ const { deriveUserRegistryPda } = await import('./pda-4KP7CURF.js');
2270
+ return deriveUserRegistryPda(this.programId, owner);
2271
+ }
2272
+ async deriveTreeConfigPda(owner) {
2273
+ const { getProgramDerivedAddress: getProgramDerivedAddress4, getAddressEncoder: getAddressEncoder4 } = await import('@solana/addresses');
2274
+ const addressEncoder = getAddressEncoder4();
2275
+ const ownerBytes = addressEncoder.encode(owner);
2276
+ const [pda] = await getProgramDerivedAddress4({
2277
+ programAddress: this.programId,
2278
+ seeds: [
2279
+ new TextEncoder().encode("agent_tree_config"),
2280
+ ownerBytes
2281
+ ]
2282
+ });
2283
+ return pda;
2284
+ }
2285
+ get systemProgramId() {
2286
+ return SYSTEM_PROGRAM_ADDRESS;
2287
+ }
2288
+ get compressionProgramId() {
2289
+ return "cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK";
2290
+ }
2291
+ };
2292
+ var SAS_PROGRAM_ID = address("22zoJMtdu4tQc2PzL74ZUT7FrwgB1Udec8DdW4yw4BdG");
2293
+ var ATTESTATION_SEED = "attestation";
2294
+ var CREDENTIAL_SEED = "credential";
2295
+ var SCHEMA_SEED = "schema";
2296
+ var SASAttestationHelper = class {
2297
+ /**
2298
+ * Derive attestation PDA for a given credential, schema, and nonce
2299
+ *
2300
+ * PDA seeds: ["attestation", credential, schema, nonce]
2301
+ *
2302
+ * @param credentialAddress - SAS Credential address (issuer)
2303
+ * @param schemaAddress - SAS Schema address (defines structure)
2304
+ * @param nonce - Unique nonce (typically the x402_payment_address)
2305
+ * @returns Attestation PDA and bump
2306
+ */
2307
+ static async deriveAttestationPda(credentialAddress, schemaAddress, nonce) {
2308
+ const [pda, bump] = await getProgramDerivedAddress({
2309
+ programAddress: SAS_PROGRAM_ID,
2310
+ seeds: [
2311
+ getUtf8Encoder().encode(ATTESTATION_SEED),
2312
+ getAddressEncoder().encode(credentialAddress),
2313
+ getAddressEncoder().encode(schemaAddress),
2314
+ getAddressEncoder().encode(nonce)
2315
+ ]
2316
+ });
2317
+ return {
2318
+ attestationPda: pda,
2319
+ bump
2320
+ };
2321
+ }
2322
+ /**
2323
+ * Derive credential PDA for an issuer
2324
+ *
2325
+ * PDA seeds: ["credential", issuer]
2326
+ *
2327
+ * @param issuer - Issuer's public key
2328
+ * @returns Credential PDA and bump
2329
+ */
2330
+ static async deriveCredentialPda(issuer) {
2331
+ const [pda, bump] = await getProgramDerivedAddress({
2332
+ programAddress: SAS_PROGRAM_ID,
2333
+ seeds: [
2334
+ getUtf8Encoder().encode(CREDENTIAL_SEED),
2335
+ getAddressEncoder().encode(issuer)
2336
+ ]
2337
+ });
2338
+ return {
2339
+ attestationPda: pda,
2340
+ bump
2341
+ };
2342
+ }
2343
+ /**
2344
+ * Derive schema PDA for a credential
2345
+ *
2346
+ * PDA seeds: ["schema", credential, schema_name]
2347
+ *
2348
+ * @param credentialAddress - Credential address
2349
+ * @param schemaName - Schema identifier
2350
+ * @returns Schema PDA and bump
2351
+ */
2352
+ static async deriveSchemaPda(credentialAddress, schemaName) {
2353
+ const [pda, bump] = await getProgramDerivedAddress({
2354
+ programAddress: SAS_PROGRAM_ID,
2355
+ seeds: [
2356
+ getUtf8Encoder().encode(SCHEMA_SEED),
2357
+ getAddressEncoder().encode(credentialAddress),
2358
+ getUtf8Encoder().encode(schemaName)
2359
+ ]
2360
+ });
2361
+ return {
2362
+ attestationPda: pda,
2363
+ bump
2364
+ };
2365
+ }
2366
+ /**
2367
+ * Serialize Ghost ownership attestation data for on-chain storage
2368
+ *
2369
+ * Format: Borsh serialization
2370
+ * - x402_payment_address: 32 bytes
2371
+ * - network: String (length-prefixed)
2372
+ * - github_username: Option<String>
2373
+ * - twitter_handle: Option<String>
2374
+ * - timestamp: i64 (8 bytes)
2375
+ *
2376
+ * @param data - Attestation data to serialize
2377
+ * @returns Serialized buffer
2378
+ */
2379
+ static serializeAttestationData(data) {
2380
+ const encoder = new TextEncoder();
2381
+ const networkBytes = encoder.encode(data.network);
2382
+ const githubBytes = data.githubUsername ? encoder.encode(data.githubUsername) : new Uint8Array();
2383
+ const twitterBytes = data.twitterHandle ? encoder.encode(data.twitterHandle) : new Uint8Array();
2384
+ const totalSize = 32 + // x402_payment_address
2385
+ 4 + networkBytes.length + // network (length prefix + data)
2386
+ 1 + (data.githubUsername ? 4 + githubBytes.length : 0) + // github option
2387
+ 1 + (data.twitterHandle ? 4 + twitterBytes.length : 0) + // twitter option
2388
+ 8;
2389
+ const buffer = new Uint8Array(totalSize);
2390
+ let offset = 0;
2391
+ const addressBytes = Buffer.from(data.x402PaymentAddress);
2392
+ buffer.set(addressBytes.slice(0, 32), offset);
2393
+ offset += 32;
2394
+ const networkLengthView = new DataView(buffer.buffer, offset, 4);
2395
+ networkLengthView.setUint32(0, networkBytes.length, true);
2396
+ offset += 4;
2397
+ buffer.set(networkBytes, offset);
2398
+ offset += networkBytes.length;
2399
+ if (data.githubUsername) {
2400
+ buffer[offset] = 1;
2401
+ offset += 1;
2402
+ const githubLengthView = new DataView(buffer.buffer, offset, 4);
2403
+ githubLengthView.setUint32(0, githubBytes.length, true);
2404
+ offset += 4;
2405
+ buffer.set(githubBytes, offset);
2406
+ offset += githubBytes.length;
2407
+ } else {
2408
+ buffer[offset] = 0;
2409
+ offset += 1;
2410
+ }
2411
+ if (data.twitterHandle) {
2412
+ buffer[offset] = 1;
2413
+ offset += 1;
2414
+ const twitterLengthView = new DataView(buffer.buffer, offset, 4);
2415
+ twitterLengthView.setUint32(0, twitterBytes.length, true);
2416
+ offset += 4;
2417
+ buffer.set(twitterBytes, offset);
2418
+ offset += twitterBytes.length;
2419
+ } else {
2420
+ buffer[offset] = 0;
2421
+ offset += 1;
2422
+ }
2423
+ const timestampView = new DataView(buffer.buffer, offset, 8);
2424
+ timestampView.setBigInt64(0, data.timestamp, true);
2425
+ return buffer;
2426
+ }
2427
+ /**
2428
+ * Get GhostSpeak default credential configuration
2429
+ *
2430
+ * This returns the official GhostSpeak credential issuer settings
2431
+ * for production use.
2432
+ *
2433
+ * @param issuer - Credential issuer address (typically the GhostSpeak program authority)
2434
+ * @returns Default credential configuration
2435
+ */
2436
+ static getDefaultCredentialConfig(issuer) {
2437
+ return {
2438
+ issuer,
2439
+ name: "GhostSpeak AI Agent Ownership",
2440
+ description: "Attestation proving ownership of an AI agent registered on the GhostSpeak protocol",
2441
+ schemaUri: "https://ghostspeak.ai/schemas/agent-ownership-v1.json"
2442
+ };
2443
+ }
2444
+ /**
2445
+ * Check if an attestation is expired
2446
+ *
2447
+ * @param expiryTimestamp - Expiry timestamp (Unix seconds)
2448
+ * @param currentTimestamp - Current timestamp (defaults to now)
2449
+ * @returns True if expired
2450
+ */
2451
+ static isAttestationExpired(expiryTimestamp, currentTimestamp) {
2452
+ const now = currentTimestamp ?? BigInt(Math.floor(Date.now() / 1e3));
2453
+ return expiryTimestamp < now;
2454
+ }
2455
+ /**
2456
+ * Calculate default expiry timestamp (1 year from now)
2457
+ *
2458
+ * @param fromTimestamp - Starting timestamp (defaults to now)
2459
+ * @returns Expiry timestamp
2460
+ */
2461
+ static calculateDefaultExpiry(fromTimestamp) {
2462
+ const now = fromTimestamp ?? BigInt(Math.floor(Date.now() / 1e3));
2463
+ const oneYear = BigInt(365 * 24 * 60 * 60);
2464
+ return now + oneYear;
2465
+ }
2466
+ /**
2467
+ * Create attestation instruction data
2468
+ *
2469
+ * NOTE: This is a helper for building the SAS create_attestation instruction.
2470
+ * The actual instruction building should be done using the SAS SDK or program IDL.
2471
+ *
2472
+ * @param config - Attestation configuration
2473
+ * @returns Prepared attestation data and PDA
2474
+ */
2475
+ static async prepareAttestation(config) {
2476
+ const { attestationPda, bump } = await this.deriveAttestationPda(
2477
+ config.credentialAddress,
2478
+ config.schemaAddress,
2479
+ config.x402PaymentAddress
2480
+ // Use x402 address as nonce
2481
+ );
2482
+ const expiryTimestamp = config.expiryTimestamp ?? this.calculateDefaultExpiry();
2483
+ const attestationData = this.serializeAttestationData({
2484
+ x402PaymentAddress: config.x402PaymentAddress,
2485
+ network: config.network,
2486
+ githubUsername: config.githubUsername,
2487
+ twitterHandle: config.twitterHandle,
2488
+ timestamp: BigInt(Math.floor(Date.now() / 1e3))
2489
+ });
2490
+ return {
2491
+ attestationData,
2492
+ attestationPda,
2493
+ bump,
2494
+ expiryTimestamp
2495
+ };
2496
+ }
2497
+ };
2498
+ var DID_DOCUMENT_SEED = "did_document";
2499
+ var GhostModule = class extends BaseModule {
2500
+ constructor(config) {
2501
+ super(config);
2502
+ }
2503
+ /**
2504
+ * Claim ownership of a Ghost using SAS attestation
2505
+ *
2506
+ * This method performs the complete claim flow:
2507
+ * 1. Derives required PDAs (attestation, DID document)
2508
+ * 2. Builds the claim_ghost instruction
2509
+ * 3. Executes the transaction
2510
+ *
2511
+ * **Prerequisites:**
2512
+ * - The claimer must have already created a SAS attestation proving ownership
2513
+ * of the agent's x402_payment_address
2514
+ * - The agent must be in Unregistered or Registered status (not already claimed)
2515
+ *
2516
+ * **Results:**
2517
+ * - Agent status transitions to Claimed
2518
+ * - DID document is auto-created with did:sol:<network>:<address>
2519
+ * - Claimer becomes the owner of the agent
2520
+ *
2521
+ * @param claimer - Transaction signer (must own the SAS attestation)
2522
+ * @param params - Claim parameters
2523
+ * @returns Transaction signature
2524
+ *
2525
+ * @example
2526
+ * ```typescript
2527
+ * const signature = await client.ghosts.claim(signer, {
2528
+ * agentAddress: 'GhostAgent123...',
2529
+ * x402PaymentAddress: 'PaymentAddr456...',
2530
+ * sasCredential: 'SASCredential789...',
2531
+ * sasSchema: 'SASSchema012...',
2532
+ * network: 'devnet',
2533
+ * ipfsMetadataUri: 'ipfs://QmHash...',
2534
+ * githubUsername: 'myusername'
2535
+ * })
2536
+ * ```
2537
+ */
2538
+ async claim(claimer, params) {
2539
+ const prepared = await this.prepareClaim(params);
2540
+ const instructionGetter = () => {
2541
+ return getClaimGhostInstruction({
2542
+ agentAccount: params.agentAddress,
2543
+ didDocument: prepared.didDocumentPda,
2544
+ sasAttestation: prepared.attestationPda,
2545
+ claimer,
2546
+ systemProgram: this.systemProgramId,
2547
+ sasCredential: params.sasCredential,
2548
+ sasSchema: params.sasSchema,
2549
+ ipfsMetadataUri: params.ipfsMetadataUri ?? null,
2550
+ network: params.network
2551
+ });
2552
+ };
2553
+ return this.execute(
2554
+ "claimGhost",
2555
+ instructionGetter,
2556
+ [claimer]
2557
+ );
2558
+ }
2559
+ /**
2560
+ * Prepare a Ghost claim by deriving all required PDAs
2561
+ *
2562
+ * This is useful for:
2563
+ * - Pre-flight validation (checking if PDAs are correct)
2564
+ * - Building custom transactions with manual PDA management
2565
+ * - Debugging claim issues
2566
+ *
2567
+ * @param params - Claim parameters
2568
+ * @returns Prepared claim data with derived PDAs
2569
+ *
2570
+ * @example
2571
+ * ```typescript
2572
+ * const prepared = await client.ghosts.prepareClaim({
2573
+ * agentAddress: 'GhostAgent123...',
2574
+ * x402PaymentAddress: 'PaymentAddr456...',
2575
+ * sasCredential: 'SASCredential789...',
2576
+ * sasSchema: 'SASSchema012...',
2577
+ * network: 'devnet'
2578
+ * })
2579
+ *
2580
+ * console.log('Attestation PDA:', prepared.attestationPda)
2581
+ * console.log('DID Document PDA:', prepared.didDocumentPda)
2582
+ * ```
2583
+ */
2584
+ async prepareClaim(params) {
2585
+ const { attestationPda, bump: attestationBump } = await SASAttestationHelper.deriveAttestationPda(
2586
+ params.sasCredential,
2587
+ params.sasSchema,
2588
+ params.x402PaymentAddress
2589
+ );
2590
+ const [didDocumentPda, didDocumentBump] = await this.deriveDidDocumentPda(params.x402PaymentAddress);
2591
+ return {
2592
+ attestationPda,
2593
+ didDocumentPda,
2594
+ attestationBump,
2595
+ didDocumentBump
2596
+ };
2597
+ }
2598
+ /**
2599
+ * Get Ghost agent account
2600
+ *
2601
+ * @param address - Agent account address
2602
+ * @returns Agent account data or null if not found
2603
+ */
2604
+ async getGhostAgent(address2) {
2605
+ return super.getAccount(address2, "getAgentDecoder");
2606
+ }
2607
+ /**
2608
+ * Get all Ghost agents (agents with type 10 - external x402 agents)
2609
+ *
2610
+ * @returns Array of Ghost agents
2611
+ */
2612
+ async getAllGhosts() {
2613
+ const GHOST_AGENT_TYPE = 10;
2614
+ return this.getGhostsByType(GHOST_AGENT_TYPE);
2615
+ }
2616
+ /**
2617
+ * Get Ghost agents by type
2618
+ *
2619
+ * @param agentType - Agent type filter (default: 10 for x402 ghosts)
2620
+ * @returns Array of matching Ghost agents
2621
+ */
2622
+ async getGhostsByType(agentType = 10) {
2623
+ const typeBytes = Buffer.alloc(1);
2624
+ typeBytes.writeUInt8(agentType, 0);
2625
+ const filters = [{
2626
+ memcmp: {
2627
+ offset: BigInt(8),
2628
+ // Skip discriminator
2629
+ bytes: typeBytes.toString("base64"),
2630
+ encoding: "base64"
2631
+ }
2632
+ }];
2633
+ return this.getProgramAccounts("getAgentDecoder", filters);
2634
+ }
2635
+ /**
2636
+ * Get claimed Ghosts by owner
2637
+ *
2638
+ * @param owner - Owner address
2639
+ * @returns Array of Ghost agents owned by the address
2640
+ */
2641
+ async getClaimedGhosts(owner) {
2642
+ const filters = [{
2643
+ memcmp: {
2644
+ offset: BigInt(9),
2645
+ // Skip discriminator + type
2646
+ bytes: owner,
2647
+ encoding: "base58"
2648
+ }
2649
+ }];
2650
+ return this.getProgramAccounts("getAgentDecoder", filters);
2651
+ }
2652
+ /**
2653
+ * Validate claim parameters
2654
+ *
2655
+ * Performs pre-flight checks to ensure claim will succeed:
2656
+ * - Agent exists and is in correct status
2657
+ * - Agent is not already claimed
2658
+ * - PDAs are correctly derived
2659
+ *
2660
+ * @param params - Claim parameters
2661
+ * @returns Validation result with error messages if any
2662
+ */
2663
+ async validateClaim(params) {
2664
+ const errors = [];
2665
+ const warnings = [];
2666
+ const validNetworks = ["devnet", "testnet", "mainnet-beta", "localnet"];
2667
+ if (!validNetworks.includes(params.network)) {
2668
+ errors.push(`Invalid network: ${params.network}. Must be one of: ${validNetworks.join(", ")}`);
2669
+ }
2670
+ if (params.ipfsMetadataUri && !params.ipfsMetadataUri.startsWith("ipfs://")) {
2671
+ warnings.push('IPFS metadata URI should start with "ipfs://"');
2672
+ }
2673
+ const agent = await this.getGhostAgent(params.agentAddress);
2674
+ if (!agent) {
2675
+ errors.push(`Agent not found at address: ${params.agentAddress}`);
2676
+ } else {
2677
+ if (agent.owner !== null) {
2678
+ errors.push(`Agent is already claimed by: ${agent.owner}`);
2679
+ }
2680
+ if (agent.agentType !== 10) {
2681
+ warnings.push(`Agent type is ${agent.agentType}, expected 10 (external x402 agent)`);
2682
+ }
2683
+ }
2684
+ return {
2685
+ valid: errors.length === 0,
2686
+ errors,
2687
+ warnings
2688
+ };
2689
+ }
2690
+ // Helper methods
2691
+ /**
2692
+ * Derive DID document PDA
2693
+ *
2694
+ * Pattern: ['did_document', x402_payment_address]
2695
+ *
2696
+ * @param x402PaymentAddress - Agent's x402 payment address
2697
+ * @returns [DID document PDA, bump]
2698
+ */
2699
+ async deriveDidDocumentPda(x402PaymentAddress) {
2700
+ const [pda, bump] = await getProgramDerivedAddress({
2701
+ programAddress: this.programId,
2702
+ seeds: [
2703
+ getUtf8Encoder().encode(DID_DOCUMENT_SEED),
2704
+ getAddressEncoder().encode(x402PaymentAddress)
2705
+ ]
2706
+ });
2707
+ return [pda, bump];
2708
+ }
2709
+ get systemProgramId() {
2710
+ return SYSTEM_PROGRAM_ADDRESS;
2711
+ }
2712
+ };
2713
+
2714
+ // src/modules/governance/GovernanceModule.ts
2715
+ var GovernanceModule = class extends BaseModule {
2716
+ // =====================================================
2717
+ // DIRECT INSTRUCTION ACCESS
2718
+ // These methods provide direct access to generated instructions
2719
+ // with minimal wrapping for maximum flexibility
2720
+ // =====================================================
2721
+ /**
2722
+ * Get initialize governance proposal instruction
2723
+ */
2724
+ getInitializeGovernanceProposalInstruction(params) {
2725
+ return getInitializeGovernanceProposalInstructionAsync(params);
2726
+ }
2727
+ // =====================================================
2728
+ // CONVENIENCE METHODS
2729
+ // These methods provide simplified access to common operations
2730
+ // =====================================================
2731
+ /**
2732
+ * Create a new governance proposal
2733
+ */
2734
+ async createProposal(params) {
2735
+ const proposalAddress = this.deriveProposalPda(params.signer.address, params.title);
2736
+ const instruction = await this.getInitializeGovernanceProposalInstruction({
2737
+ proposal: proposalAddress,
2738
+ proposer: params.signer,
2739
+ title: params.title,
2740
+ description: params.description,
2741
+ proposalType: { kind: params.proposalType, data: {} },
2742
+ executionParams: {
2743
+ instructions: [],
2744
+ accounts: [],
2745
+ targetProgram: proposalAddress,
2746
+ executeAfter: BigInt(params.executionDelay ?? 0)
2747
+ },
2748
+ proposalId: BigInt(Date.now())
2749
+ });
2750
+ return this.execute("createProposal", () => instruction, [params.signer]);
2751
+ }
2752
+ // =====================================================
2753
+ // QUERY OPERATIONS
2754
+ // =====================================================
2755
+ /**
2756
+ * Get governance proposal account
2757
+ */
2758
+ async getProposal(address2) {
2759
+ return super.getAccount(address2, "getGovernanceProposalDecoder");
2760
+ }
2761
+ /**
2762
+ * Get all active proposals
2763
+ */
2764
+ async getActiveProposals() {
2765
+ return this.getProgramAccounts("getGovernanceProposalDecoder");
2766
+ }
2767
+ /**
2768
+ * Get proposals by proposer
2769
+ */
2770
+ async getProposalsByProposer(proposer) {
2771
+ const filters = [{
2772
+ memcmp: {
2773
+ offset: BigInt(8),
2774
+ // Skip discriminator
2775
+ bytes: proposer,
2776
+ encoding: "base58"
2777
+ }
2778
+ }];
2779
+ return this.getProgramAccounts("getGovernanceProposalDecoder", filters);
2780
+ }
2781
+ /**
2782
+ * Get proposals by status
2783
+ */
2784
+ async getProposalsByStatus(_status) {
2785
+ const allProposals = await this.getProgramAccounts("getGovernanceProposalDecoder");
2786
+ return allProposals.filter((_proposal) => {
2787
+ return allProposals.length > 0;
2788
+ });
2789
+ }
2790
+ // =====================================================
2791
+ // HELPER METHODS
2792
+ // =====================================================
2793
+ deriveProposalPda(proposer, title) {
2794
+ return `proposal_${proposer}_${title}`;
2795
+ }
2796
+ };
2797
+
2798
+ // src/modules/multisig/MultisigModule.ts
2799
+ var MultisigModule = class extends BaseModule {
2800
+ /**
2801
+ * Create a new multisig account
2802
+ */
2803
+ async createMultisig(params) {
2804
+ throw new Error("createMultisig: Instruction not available - requires IDL regeneration");
2805
+ }
2806
+ /**
2807
+ * Create a proposal (Uses Governance Protocol)
2808
+ *
2809
+ * Note: This creates a GovernanceProposal. The proposer must be a signer.
2810
+ */
2811
+ async createProposal(params) {
2812
+ const instruction = await getInitializeGovernanceProposalInstructionAsync({
2813
+ proposer: params.proposer,
2814
+ proposalId: params.proposalId,
2815
+ title: params.title,
2816
+ description: params.description,
2817
+ proposalType: params.proposalType,
2818
+ executionParams: params.executionParams
2819
+ }, { programAddress: this.programId });
2820
+ return this.execute("createProposal", () => instruction, [params.proposer]);
2821
+ }
2822
+ /**
2823
+ * Execute a proposal (Note: Approval/voting removed, use protocol_config instead)
2824
+ */
2825
+ async executeProposal(params) {
2826
+ throw new Error("executeProposal: Use protocol_config instructions for execution");
2827
+ }
2828
+ };
2829
+
2830
+ // src/modules/did/did-types.ts
2831
+ var DID_DOCUMENT_SEED2 = "did_document";
2832
+ var VerificationMethodType = /* @__PURE__ */ ((VerificationMethodType2) => {
2833
+ VerificationMethodType2["Ed25519VerificationKey2020"] = "Ed25519VerificationKey2020";
2834
+ VerificationMethodType2["X25519KeyAgreementKey2020"] = "X25519KeyAgreementKey2020";
2835
+ VerificationMethodType2["EcdsaSecp256k1VerificationKey2019"] = "EcdsaSecp256k1VerificationKey2019";
2836
+ return VerificationMethodType2;
2837
+ })(VerificationMethodType || {});
2838
+ var VerificationRelationship = /* @__PURE__ */ ((VerificationRelationship2) => {
2839
+ VerificationRelationship2["Authentication"] = "authentication";
2840
+ VerificationRelationship2["AssertionMethod"] = "assertionMethod";
2841
+ VerificationRelationship2["KeyAgreement"] = "keyAgreement";
2842
+ VerificationRelationship2["CapabilityInvocation"] = "capabilityInvocation";
2843
+ VerificationRelationship2["CapabilityDelegation"] = "capabilityDelegation";
2844
+ return VerificationRelationship2;
2845
+ })(VerificationRelationship || {});
2846
+ var ServiceEndpointType = /* @__PURE__ */ ((ServiceEndpointType2) => {
2847
+ ServiceEndpointType2["AIAgentService"] = "AIAgentService";
2848
+ ServiceEndpointType2["DIDCommMessaging"] = "DIDCommMessaging";
2849
+ ServiceEndpointType2["CredentialRepository"] = "CredentialRepository";
2850
+ ServiceEndpointType2["LinkedDomains"] = "LinkedDomains";
2851
+ ServiceEndpointType2["Custom"] = "Custom";
2852
+ return ServiceEndpointType2;
2853
+ })(ServiceEndpointType || {});
2854
+ var DidError = /* @__PURE__ */ ((DidError2) => {
2855
+ DidError2["AlreadyDeactivated"] = "AlreadyDeactivated";
2856
+ DidError2["TooManyVerificationMethods"] = "TooManyVerificationMethods";
2857
+ DidError2["TooManyServiceEndpoints"] = "TooManyServiceEndpoints";
2858
+ DidError2["DuplicateMethodId"] = "DuplicateMethodId";
2859
+ DidError2["DuplicateServiceId"] = "DuplicateServiceId";
2860
+ DidError2["MethodNotFound"] = "MethodNotFound";
2861
+ DidError2["ServiceNotFound"] = "ServiceNotFound";
2862
+ DidError2["InvalidDidFormat"] = "InvalidDidFormat";
2863
+ DidError2["UnauthorizedDidOperation"] = "UnauthorizedDidOperation";
2864
+ DidError2["DidDeactivated"] = "DidDeactivated";
2865
+ return DidError2;
2866
+ })(DidError || {});
2867
+ var DidErrorClass = class extends Error {
2868
+ code;
2869
+ constructor(code, message) {
2870
+ super(message || code);
2871
+ this.name = "DidError";
2872
+ this.code = code;
2873
+ }
2874
+ };
2875
+ async function deriveDidDocumentPda(programId, controller) {
2876
+ const [address2, bump] = await getProgramDerivedAddress({
2877
+ programAddress: programId,
2878
+ seeds: [
2879
+ new TextEncoder().encode(DID_DOCUMENT_SEED2),
2880
+ getAddressEncoder().encode(controller)
2881
+ ]
2882
+ });
2883
+ return [address2, bump];
2884
+ }
2885
+ function generateDidString(network, pubkey) {
2886
+ const normalizedNetwork = network === "mainnet" ? "mainnet-beta" : network;
2887
+ return `did:sol:${normalizedNetwork}:${pubkey.toString()}`;
2888
+ }
2889
+ function validateDidString(did) {
2890
+ if (!did.startsWith("did:sol:")) {
2891
+ throw new DidErrorClass(
2892
+ "InvalidDidFormat" /* InvalidDidFormat */,
2893
+ 'DID must start with "did:sol:"'
2894
+ );
2895
+ }
2896
+ const parts = did.split(":");
2897
+ if (parts.length !== 4) {
2898
+ throw new DidErrorClass(
2899
+ "InvalidDidFormat" /* InvalidDidFormat */,
2900
+ 'DID must have format "did:sol:network:identifier"'
2901
+ );
2902
+ }
2903
+ const validNetworks = ["mainnet-beta", "devnet", "testnet", "localnet"];
2904
+ if (!validNetworks.includes(parts[2])) {
2905
+ throw new DidErrorClass(
2906
+ "InvalidDidFormat" /* InvalidDidFormat */,
2907
+ `Invalid network "${parts[2]}". Must be one of: ${validNetworks.join(", ")}`
2908
+ );
2909
+ }
2910
+ try {
2911
+ bs58.decode(parts[3]);
2912
+ } catch {
2913
+ throw new DidErrorClass(
2914
+ "InvalidDidFormat" /* InvalidDidFormat */,
2915
+ "DID identifier must be a valid base58-encoded Solana public key"
2916
+ );
2917
+ }
2918
+ }
2919
+ function parseDidString(did) {
2920
+ validateDidString(did);
2921
+ const parts = did.split(":");
2922
+ return {
2923
+ method: parts[1],
2924
+ network: parts[2],
2925
+ identifier: parts[3]
2926
+ };
2927
+ }
2928
+ function exportAsW3CDidDocument(didDocument) {
2929
+ const verificationMethod = didDocument.verificationMethods.filter((m) => !m.revoked).map((method) => ({
2930
+ id: `${didDocument.did}#${method.id}`,
2931
+ type: method.methodType,
2932
+ controller: method.controller,
2933
+ publicKeyMultibase: method.publicKeyMultibase
2934
+ }));
2935
+ const authentication = didDocument.verificationMethods.filter((m) => !m.revoked && m.relationships.includes("authentication" /* Authentication */)).map((m) => `${didDocument.did}#${m.id}`);
2936
+ const assertionMethod = didDocument.verificationMethods.filter((m) => !m.revoked && m.relationships.includes("assertionMethod" /* AssertionMethod */)).map((m) => `${didDocument.did}#${m.id}`);
2937
+ const keyAgreement = didDocument.verificationMethods.filter((m) => !m.revoked && m.relationships.includes("keyAgreement" /* KeyAgreement */)).map((m) => `${didDocument.did}#${m.id}`);
2938
+ const capabilityInvocation = didDocument.verificationMethods.filter((m) => !m.revoked && m.relationships.includes("capabilityInvocation" /* CapabilityInvocation */)).map((m) => `${didDocument.did}#${m.id}`);
2939
+ const capabilityDelegation = didDocument.verificationMethods.filter((m) => !m.revoked && m.relationships.includes("capabilityDelegation" /* CapabilityDelegation */)).map((m) => `${didDocument.did}#${m.id}`);
2940
+ const service = didDocument.serviceEndpoints.map((endpoint) => ({
2941
+ id: `${didDocument.did}#${endpoint.id}`,
2942
+ type: endpoint.serviceType,
2943
+ serviceEndpoint: endpoint.serviceEndpoint,
2944
+ description: endpoint.description || void 0
2945
+ }));
2946
+ return {
2947
+ "@context": didDocument.context,
2948
+ id: didDocument.did,
2949
+ controller: didDocument.controller.toString(),
2950
+ verificationMethod,
2951
+ authentication: authentication.length > 0 ? authentication : void 0,
2952
+ assertionMethod: assertionMethod.length > 0 ? assertionMethod : void 0,
2953
+ keyAgreement: keyAgreement.length > 0 ? keyAgreement : void 0,
2954
+ capabilityInvocation: capabilityInvocation.length > 0 ? capabilityInvocation : void 0,
2955
+ capabilityDelegation: capabilityDelegation.length > 0 ? capabilityDelegation : void 0,
2956
+ service: service.length > 0 ? service : void 0,
2957
+ alsoKnownAs: didDocument.alsoKnownAs.length > 0 ? didDocument.alsoKnownAs : void 0
2958
+ };
2959
+ }
2960
+ function createEd25519VerificationMethod(id, controller, publicKey, relationships = ["authentication" /* Authentication */]) {
2961
+ const publicKeyMultibase = `z${publicKey}`;
2962
+ return {
2963
+ id,
2964
+ methodType: "Ed25519VerificationKey2020" /* Ed25519VerificationKey2020 */,
2965
+ controller,
2966
+ publicKeyMultibase,
2967
+ relationships,
2968
+ createdAt: Math.floor(Date.now() / 1e3),
2969
+ revoked: false
2970
+ };
2971
+ }
2972
+ function createServiceEndpoint(id, serviceType, serviceEndpoint, description = "") {
2973
+ return {
2974
+ id,
2975
+ serviceType,
2976
+ serviceEndpoint,
2977
+ description
2978
+ };
2979
+ }
2980
+ function isDidActive(didDocument) {
2981
+ return !didDocument.deactivated;
2982
+ }
2983
+ function getMethodsForRelationship(didDocument, relationship) {
2984
+ return didDocument.verificationMethods.filter(
2985
+ (m) => !m.revoked && m.relationships.includes(relationship)
2986
+ );
2987
+ }
2988
+ function canPerformAction(didDocument, publicKey, relationship) {
2989
+ if (publicKey.toString() === didDocument.controller.toString()) {
2990
+ return true;
2991
+ }
2992
+ const pubkeyMultibase = `z${publicKey.toString()}`;
2993
+ return didDocument.verificationMethods.some(
2994
+ (method) => !method.revoked && method.publicKeyMultibase === pubkeyMultibase && method.relationships.includes(relationship)
2995
+ );
2996
+ }
2997
+ function didDocumentToJson(didDocument, pretty = true) {
2998
+ const w3cDoc = exportAsW3CDidDocument(didDocument);
2999
+ return pretty ? JSON.stringify(w3cDoc, null, 2) : JSON.stringify(w3cDoc);
3000
+ }
3001
+ function getNetworkFromDid(did) {
3002
+ const parts = parseDidString(did);
3003
+ return parts.network;
3004
+ }
3005
+ function getIdentifierFromDid(did) {
3006
+ const parts = parseDidString(did);
3007
+ return parts.identifier;
3008
+ }
3009
+ var base58Encode = (data) => bs58.encode(data);
3010
+ var DEFAULT_PROGRAM_ID = "GHosT3wqDfNq9bKz8dNEQ1F5mLuN7bKdNYx3Z1111111";
3011
+ var CredentialKind = /* @__PURE__ */ ((CredentialKind2) => {
3012
+ CredentialKind2["AgentIdentity"] = "AgentIdentity";
3013
+ CredentialKind2["ReputationScore"] = "ReputationScore";
3014
+ CredentialKind2["JobCompletion"] = "JobCompletion";
3015
+ CredentialKind2["DelegatedSigner"] = "DelegatedSigner";
3016
+ CredentialKind2["Custom"] = "Custom";
3017
+ return CredentialKind2;
3018
+ })(CredentialKind || {});
3019
+ var CredentialStatus = /* @__PURE__ */ ((CredentialStatus2) => {
3020
+ CredentialStatus2["Pending"] = "Pending";
3021
+ CredentialStatus2["Active"] = "Active";
3022
+ CredentialStatus2["Revoked"] = "Revoked";
3023
+ CredentialStatus2["Expired"] = "Expired";
3024
+ return CredentialStatus2;
3025
+ })(CredentialStatus || {});
3026
+ var CredentialModule = class {
3027
+ programId;
3028
+ didModule;
3029
+ constructor(programId = DEFAULT_PROGRAM_ID, didModule) {
3030
+ this.programId = programId;
3031
+ this.didModule = didModule;
3032
+ }
3033
+ /**
3034
+ * Set the DID module for enhanced DID resolution
3035
+ * This enables automatic DID creation and resolution for credentials
3036
+ */
3037
+ setDidModule(didModule) {
3038
+ this.didModule = didModule;
3039
+ }
3040
+ // --------------------------------------------------------------------------
3041
+ // Hashing
3042
+ // --------------------------------------------------------------------------
3043
+ hashSubjectData(subjectData) {
3044
+ const json = JSON.stringify(subjectData, Object.keys(subjectData).sort());
3045
+ return sha256(new TextEncoder().encode(json));
3046
+ }
3047
+ generateCredentialId(kind, subject) {
3048
+ const timestamp = Date.now();
3049
+ const input = `${kind}-${subject}-${timestamp}`;
3050
+ const hash = sha256(new TextEncoder().encode(input));
3051
+ const shortHash = base58Encode(hash.slice(0, 8));
3052
+ return `${kind.toLowerCase()}-${shortHash}`;
3053
+ }
3054
+ // --------------------------------------------------------------------------
3055
+ // Export W3C
3056
+ // --------------------------------------------------------------------------
3057
+ exportAsW3CCredential(credential, template, credentialType, subjectData, options) {
3058
+ const network = options?.network || "mainnet";
3059
+ const issuerDid = generateDidString(network, this.programId);
3060
+ const subjectDid = generateDidString(network, credential.subject);
3061
+ const statusId = `solana:${this.programId}:credential:${credential.credentialId}`;
3062
+ return {
3063
+ "@context": [
3064
+ "https://www.w3.org/ns/credentials/v2",
3065
+ "https://w3id.org/security/data-integrity/v2",
3066
+ "https://ghostspeak.io/ns/credentials/v1"
3067
+ ],
3068
+ type: ["VerifiableCredential", `GhostSpeak${credentialType.kind}Credential`],
3069
+ id: `urn:ghostspeak:${credential.credentialId}`,
3070
+ issuer: {
3071
+ id: issuerDid,
3072
+ name: "GhostSpeak Protocol"
3073
+ },
3074
+ validFrom: new Date(credential.issuedAt * 1e3).toISOString(),
3075
+ validUntil: credential.expiresAt ? new Date(credential.expiresAt * 1e3).toISOString() : void 0,
3076
+ credentialSubject: {
3077
+ id: subjectDid,
3078
+ ...subjectData
3079
+ },
3080
+ credentialSchema: {
3081
+ id: credentialType.schemaUri,
3082
+ type: "JsonSchema"
3083
+ },
3084
+ credentialStatus: {
3085
+ id: statusId,
3086
+ type: "SolanaAccountStatus2025",
3087
+ statusPurpose: "revocation"
3088
+ },
3089
+ relatedResource: options?.includeRelatedResource ? [
3090
+ {
3091
+ id: credential.subjectDataUri,
3092
+ digestMultibase: `mEi${base58Encode(credential.subjectDataHash)}`
3093
+ }
3094
+ ] : void 0,
3095
+ proof: {
3096
+ type: "DataIntegrityProof",
3097
+ created: new Date(credential.issuedAt * 1e3).toISOString(),
3098
+ verificationMethod: `${issuerDid}#key-1`,
3099
+ cryptosuite: "eddsa-rdfc-2022",
3100
+ proofPurpose: "assertionMethod",
3101
+ proofValue: base58Encode(credential.signature)
3102
+ }
3103
+ };
3104
+ }
3105
+ /**
3106
+ * Export credential with DID resolution
3107
+ * Resolves DIDs for issuer and subject to get full DID documents
3108
+ *
3109
+ * @param credential - Credential to export
3110
+ * @param template - Credential template
3111
+ * @param credentialType - Credential type
3112
+ * @param subjectData - Subject data
3113
+ * @param options - Export options
3114
+ * @returns W3C credential with resolved DIDs
3115
+ */
3116
+ async exportWithDidResolution(credential, template, credentialType, subjectData, options) {
3117
+ if (!this.didModule) {
3118
+ return this.exportAsW3CCredential(
3119
+ credential,
3120
+ template,
3121
+ credentialType,
3122
+ subjectData,
3123
+ options
3124
+ );
3125
+ }
3126
+ const network = options?.network || "mainnet";
3127
+ const issuerDid = generateDidString(network, this.programId);
3128
+ const subjectDid = generateDidString(network, credential.subject);
3129
+ const issuerDidDoc = await this.didModule.resolve(this.programId).catch(() => null);
3130
+ await this.didModule.resolve(credential.subject).catch(() => null);
3131
+ const statusId = `solana:${this.programId}:credential:${credential.credentialId}`;
3132
+ const verificationMethod = issuerDidDoc?.verificationMethods?.[0] ? `${issuerDid}#${issuerDidDoc.verificationMethods[0].id}` : `${issuerDid}#key-1`;
3133
+ return {
3134
+ "@context": [
3135
+ "https://www.w3.org/ns/credentials/v2",
3136
+ "https://w3id.org/security/data-integrity/v2",
3137
+ "https://ghostspeak.io/ns/credentials/v1"
3138
+ ],
3139
+ type: ["VerifiableCredential", `GhostSpeak${credentialType.kind}Credential`],
3140
+ id: `urn:ghostspeak:${credential.credentialId}`,
3141
+ issuer: {
3142
+ id: issuerDid,
3143
+ name: "GhostSpeak Protocol"
3144
+ },
3145
+ validFrom: new Date(credential.issuedAt * 1e3).toISOString(),
3146
+ validUntil: credential.expiresAt ? new Date(credential.expiresAt * 1e3).toISOString() : void 0,
3147
+ credentialSubject: {
3148
+ id: subjectDid,
3149
+ ...subjectData
3150
+ },
3151
+ credentialSchema: {
3152
+ id: credentialType.schemaUri,
3153
+ type: "JsonSchema"
3154
+ },
3155
+ credentialStatus: {
3156
+ id: statusId,
3157
+ type: "SolanaAccountStatus2025",
3158
+ statusPurpose: "revocation"
3159
+ },
3160
+ relatedResource: options?.includeRelatedResource ? [
3161
+ {
3162
+ id: credential.subjectDataUri,
3163
+ digestMultibase: `mEi${base58Encode(credential.subjectDataHash)}`
3164
+ }
3165
+ ] : void 0,
3166
+ proof: {
3167
+ type: "DataIntegrityProof",
3168
+ created: new Date(credential.issuedAt * 1e3).toISOString(),
3169
+ verificationMethod,
3170
+ cryptosuite: "eddsa-rdfc-2022",
3171
+ proofPurpose: "assertionMethod",
3172
+ proofValue: base58Encode(credential.signature)
3173
+ }
3174
+ };
3175
+ }
3176
+ // --------------------------------------------------------------------------
3177
+ // Helpers for Subject Building
3178
+ // --------------------------------------------------------------------------
3179
+ static buildAgentIdentitySubject(params) {
3180
+ return params;
3181
+ }
3182
+ // --------------------------------------------------------------------------
3183
+ // x402 Agent Credential Issuance
3184
+ // --------------------------------------------------------------------------
3185
+ /**
3186
+ * Issue an AgentIdentity credential for a newly registered x402 agent
3187
+ *
3188
+ * This creates a W3C Verifiable Credential that can be:
3189
+ * - Stored on-chain for reputation
3190
+ * - Exported as standard W3C VC JSON
3191
+ * - Verified by third parties
3192
+ *
3193
+ * @example
3194
+ * ```typescript
3195
+ * const result = await credentialModule.issueX402AgentCredential({
3196
+ * agentAddress: 'EPjFWdd5...',
3197
+ * agentId: 'x402-abc123',
3198
+ * owner: 'HN7cAB...',
3199
+ * name: 'My Coinbase Agent',
3200
+ * serviceEndpoint: 'https://my-agent.com/api',
3201
+ * frameworkOrigin: 'coinbase-x402',
3202
+ * x402PaymentAddress: 'EPjFWdd5...',
3203
+ * x402AcceptedTokens: ['EPjFWdd5...'],
3204
+ * x402PricePerCall: '1000000'
3205
+ * })
3206
+ * ```
3207
+ */
3208
+ issueX402AgentCredential(params) {
3209
+ const now = Math.floor(Date.now() / 1e3);
3210
+ const subjectData = {
3211
+ agentId: params.agentId,
3212
+ owner: params.owner,
3213
+ name: params.name,
3214
+ capabilities: params.capabilities || [],
3215
+ serviceEndpoint: params.serviceEndpoint,
3216
+ frameworkOrigin: params.frameworkOrigin,
3217
+ x402Enabled: true,
3218
+ x402PaymentAddress: params.x402PaymentAddress,
3219
+ x402AcceptedTokens: params.x402AcceptedTokens,
3220
+ x402PricePerCall: params.x402PricePerCall,
3221
+ registeredAt: now,
3222
+ verifiedAt: now,
3223
+ type: "external-x402-agent",
3224
+ verificationResponseTimeMs: params.verificationResponseTimeMs
3225
+ };
3226
+ const credentialId = this.generateCredentialId(
3227
+ "AgentIdentity" /* AgentIdentity */,
3228
+ params.agentAddress
3229
+ );
3230
+ const subjectDataHash = this.hashSubjectData(subjectData);
3231
+ const credential = {
3232
+ template: `x402-agent-identity-template`,
3233
+ subject: params.agentAddress,
3234
+ issuer: this.programId,
3235
+ credentialId,
3236
+ subjectDataHash,
3237
+ subjectDataUri: `data:application/json;base64,${Buffer.from(JSON.stringify(subjectData)).toString("base64")}`,
3238
+ status: "Active" /* Active */,
3239
+ signature: subjectDataHash,
3240
+ // Self-signed with hash (for demo; real impl would sign with authority key)
3241
+ issuedAt: now
3242
+ };
3243
+ const credentialType = {
3244
+ authority: this.programId,
3245
+ name: "x402 Agent Identity",
3246
+ kind: "AgentIdentity" /* AgentIdentity */,
3247
+ schemaUri: "https://ghostspeak.io/schemas/x402-agent-identity-v1.json",
3248
+ description: "Verifiable credential for x402-compatible AI agents registered with GhostSpeak",
3249
+ isActive: true,
3250
+ totalIssued: 1,
3251
+ createdAt: now
3252
+ };
3253
+ const template = {
3254
+ credentialType: credentialType.authority,
3255
+ name: "x402 Agent Identity",
3256
+ imageUri: "https://ghostspeak.io/assets/credential-badge-x402.png",
3257
+ issuer: this.programId,
3258
+ isActive: true,
3259
+ totalIssued: 1,
3260
+ createdAt: now
3261
+ };
3262
+ const w3cCredential = this.exportAsW3CCredential(
3263
+ credential,
3264
+ template,
3265
+ credentialType,
3266
+ subjectData,
3267
+ { network: params.network || "devnet", includeRelatedResource: true }
3268
+ );
3269
+ return {
3270
+ credentialId,
3271
+ credential,
3272
+ w3cCredential,
3273
+ subjectData
3274
+ };
3275
+ }
3276
+ /**
3277
+ * Export an existing credential to W3C JSON format
3278
+ */
3279
+ exportCredentialToJSON(credential, subjectData, options) {
3280
+ const template = {
3281
+ credentialType: "x402-agent",
3282
+ name: credential.credentialId.includes("agentidentity") ? "Agent Identity" : "Custom",
3283
+ imageUri: "https://ghostspeak.io/assets/credential-badge.png",
3284
+ issuer: credential.issuer,
3285
+ isActive: true,
3286
+ totalIssued: 1,
3287
+ createdAt: credential.issuedAt
3288
+ };
3289
+ const credentialType = {
3290
+ authority: credential.issuer,
3291
+ name: "GhostSpeak Credential",
3292
+ kind: "AgentIdentity" /* AgentIdentity */,
3293
+ schemaUri: "https://ghostspeak.io/schemas/credential-v1.json",
3294
+ description: "GhostSpeak verifiable credential",
3295
+ isActive: true,
3296
+ totalIssued: 1,
3297
+ createdAt: credential.issuedAt
3298
+ };
3299
+ const w3c = this.exportAsW3CCredential(
3300
+ credential,
3301
+ template,
3302
+ credentialType,
3303
+ subjectData,
3304
+ { network: options?.network || "devnet", includeRelatedResource: true }
3305
+ );
3306
+ return options?.pretty ? JSON.stringify(w3c, null, 2) : JSON.stringify(w3c);
3307
+ }
3308
+ };
3309
+
3310
+ // src/modules/reputation/ReputationModule.ts
3311
+ init_reputation_tag_engine();
3312
+ var ReputationModule = class extends BaseModule {
3313
+ calculator;
3314
+ tagEngine;
3315
+ constructor(config) {
3316
+ super(config);
3317
+ this.calculator = new ReputationCalculator();
3318
+ this.tagEngine = new ReputationTagEngine();
3319
+ }
3320
+ /**
3321
+ * Calculate reputation change for a job
3322
+ */
3323
+ calculateReputationChange(currentData, jobPerformance) {
3324
+ return this.calculator.calculateReputation(currentData, jobPerformance);
3325
+ }
3326
+ /**
3327
+ * Get tier name from tier enum
3328
+ */
3329
+ getTierName(tier) {
3330
+ switch (tier) {
3331
+ case "None" /* None */:
3332
+ return "Unranked";
3333
+ case "Bronze" /* Bronze */:
3334
+ return "Bronze";
3335
+ case "Silver" /* Silver */:
3336
+ return "Silver";
3337
+ case "Gold" /* Gold */:
3338
+ return "Gold";
3339
+ case "Platinum" /* Platinum */:
3340
+ return "Platinum";
3341
+ default:
3342
+ return "Unknown";
3343
+ }
3344
+ }
3345
+ /**
3346
+ * Get tier from score
3347
+ */
3348
+ getTierFromScore(score) {
3349
+ if (score >= REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD) {
3350
+ return "Platinum" /* Platinum */;
3351
+ } else if (score >= REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD) {
3352
+ return "Gold" /* Gold */;
3353
+ } else if (score >= REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD) {
3354
+ return "Silver" /* Silver */;
3355
+ } else if (score >= REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD) {
3356
+ return "Bronze" /* Bronze */;
3357
+ }
3358
+ return "None" /* None */;
3359
+ }
3360
+ /**
3361
+ * Get badge display name
3362
+ */
3363
+ getBadgeName(badge) {
3364
+ switch (badge) {
3365
+ case "FirstJob" /* FirstJob */:
3366
+ return "First Job";
3367
+ case "TenJobs" /* TenJobs */:
3368
+ return "10 Jobs";
3369
+ case "HundredJobs" /* HundredJobs */:
3370
+ return "100 Jobs";
3371
+ case "ThousandJobs" /* ThousandJobs */:
3372
+ return "1000 Jobs";
3373
+ case "PerfectRating" /* PerfectRating */:
3374
+ return "Perfect Rating";
3375
+ case "QuickResponder" /* QuickResponder */:
3376
+ return "Quick Responder";
3377
+ case "DisputeResolver" /* DisputeResolver */:
3378
+ return "Dispute Resolver";
3379
+ case "CategoryExpert" /* CategoryExpert */:
3380
+ return "Category Expert";
3381
+ case "CrossCategoryMaster" /* CrossCategoryMaster */:
3382
+ return "Cross-Category Master";
3383
+ default:
3384
+ return "Unknown Badge";
3385
+ }
3386
+ }
3387
+ /**
3388
+ * Calculate estimated APY boost from reputation
3389
+ */
3390
+ calculateApyBoost(score) {
3391
+ return Math.floor(score / 1e3) * 50;
3392
+ }
3393
+ /**
3394
+ * Get reputation tier color for UI
3395
+ */
3396
+ getTierColor(tier) {
3397
+ switch (tier) {
3398
+ case "Platinum" /* Platinum */:
3399
+ return "#E5E4E2";
3400
+ // Platinum gray
3401
+ case "Gold" /* Gold */:
3402
+ return "#FFD700";
3403
+ // Gold
3404
+ case "Silver" /* Silver */:
3405
+ return "#C0C0C0";
3406
+ // Silver
3407
+ case "Bronze" /* Bronze */:
3408
+ return "#CD7F32";
3409
+ // Bronze
3410
+ default:
3411
+ return "#808080";
3412
+ }
3413
+ }
3414
+ /**
3415
+ * Create default reputation data for new agents
3416
+ */
3417
+ createDefaultReputationData(agentAddress) {
3418
+ return {
3419
+ agent: agentAddress,
3420
+ overallScore: 5e3,
3421
+ // Start at 50%
3422
+ totalJobsCompleted: 0,
3423
+ totalJobsFailed: 0,
3424
+ avgResponseTime: 0,
3425
+ disputesAgainst: 0,
3426
+ disputesResolved: 0,
3427
+ lastUpdated: Math.floor(Date.now() / 1e3),
3428
+ categoryReputations: [],
3429
+ badges: [],
3430
+ performanceHistory: [],
3431
+ factors: {
3432
+ completionWeight: 25,
3433
+ qualityWeight: 25,
3434
+ timelinessWeight: 20,
3435
+ satisfactionWeight: 20,
3436
+ disputeWeight: 10
3437
+ }
3438
+ };
3439
+ }
3440
+ /**
3441
+ * Check if agent qualifies for a specific tier
3442
+ */
3443
+ qualifiesForTier(score, tier) {
3444
+ switch (tier) {
3445
+ case "Platinum" /* Platinum */:
3446
+ return score >= REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD;
3447
+ case "Gold" /* Gold */:
3448
+ return score >= REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD;
3449
+ case "Silver" /* Silver */:
3450
+ return score >= REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD;
3451
+ case "Bronze" /* Bronze */:
3452
+ return score >= REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD;
3453
+ default:
3454
+ return true;
3455
+ }
3456
+ }
3457
+ /**
3458
+ * Calculate points needed for next tier
3459
+ */
3460
+ pointsToNextTier(score) {
3461
+ const currentTier = this.getTierFromScore(score);
3462
+ switch (currentTier) {
3463
+ case "None" /* None */:
3464
+ return { nextTier: "Bronze" /* Bronze */, pointsNeeded: REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD - score };
3465
+ case "Bronze" /* Bronze */:
3466
+ return { nextTier: "Silver" /* Silver */, pointsNeeded: REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD - score };
3467
+ case "Silver" /* Silver */:
3468
+ return { nextTier: "Gold" /* Gold */, pointsNeeded: REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD - score };
3469
+ case "Gold" /* Gold */:
3470
+ return { nextTier: "Platinum" /* Platinum */, pointsNeeded: REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD - score };
3471
+ case "Platinum" /* Platinum */:
3472
+ return null;
3473
+ // Already at max tier
3474
+ default:
3475
+ return null;
3476
+ }
3477
+ }
3478
+ // =====================================================
3479
+ // PAYAI INTEGRATION
3480
+ // =====================================================
3481
+ /**
3482
+ * Record a PayAI payment event to update reputation
3483
+ *
3484
+ * Converts PayAI webhook data to JobPerformance format and
3485
+ * calculates reputation change.
3486
+ *
3487
+ * @param record - PayAI reputation record from webhook
3488
+ * @param currentData - Current agent reputation data (fetched from on-chain or cache)
3489
+ * @returns Reputation calculation result
3490
+ */
3491
+ recordPayAIPayment(record, currentData) {
3492
+ const jobPerformance = this.payAIRecordToJobPerformance(record);
3493
+ return this.calculateReputationChange(currentData, jobPerformance);
3494
+ }
3495
+ /**
3496
+ * Convert a PayAI reputation record to JobPerformance format
3497
+ *
3498
+ * PayAI provides basic payment data, so we derive quality metrics
3499
+ * from response time and success status.
3500
+ */
3501
+ payAIRecordToJobPerformance(record) {
3502
+ const qualityRating = this.estimateQualityFromResponseTime(record.responseTimeMs);
3503
+ const expectedDuration = this.estimateExpectedDuration(record.amount);
3504
+ return {
3505
+ completed: record.success,
3506
+ qualityRating,
3507
+ expectedDuration,
3508
+ actualDuration: Math.ceil(record.responseTimeMs / 1e3),
3509
+ // Convert to seconds
3510
+ clientSatisfaction: record.success ? qualityRating : 20,
3511
+ // Lower satisfaction on failure
3512
+ hadDispute: false,
3513
+ // PayAI webhook doesn't include dispute info
3514
+ disputeResolvedFavorably: false,
3515
+ category: this.categorizeFromNetwork(record.network),
3516
+ paymentAmount: Number(record.amount) / 1e6
3517
+ // Convert from base units (e.g., USDC 6 decimals)
3518
+ };
3519
+ }
3520
+ /**
3521
+ * Estimate quality rating from response time
3522
+ *
3523
+ * Fast responses (< 500ms) = 100 quality
3524
+ * Average responses (500ms-2s) = 70-90 quality
3525
+ * Slow responses (2s-10s) = 40-70 quality
3526
+ * Very slow responses (> 10s) = 20-40 quality
3527
+ */
3528
+ estimateQualityFromResponseTime(responseTimeMs) {
3529
+ if (responseTimeMs <= 500) {
3530
+ return 100;
3531
+ } else if (responseTimeMs <= 2e3) {
3532
+ return Math.round(90 - (responseTimeMs - 500) / 1500 * 20);
3533
+ } else if (responseTimeMs <= 1e4) {
3534
+ return Math.round(70 - (responseTimeMs - 2e3) / 8e3 * 30);
3535
+ } else {
3536
+ return Math.max(20, Math.round(40 - (responseTimeMs - 1e4) / 5e4 * 20));
3537
+ }
3538
+ }
3539
+ /**
3540
+ * Estimate expected duration based on payment amount
3541
+ *
3542
+ * Larger payments = longer expected processing time
3543
+ */
3544
+ estimateExpectedDuration(amountBaseUnits) {
3545
+ const amountUSDC = Number(amountBaseUnits) / 1e6;
3546
+ return Math.max(2, Math.ceil(2 + amountUSDC * 10));
3547
+ }
3548
+ /**
3549
+ * Categorize payment by network
3550
+ */
3551
+ categorizeFromNetwork(network) {
3552
+ switch (network) {
3553
+ case "solana":
3554
+ return "ai-services-solana";
3555
+ case "base":
3556
+ return "ai-services-base";
3557
+ case "ethereum":
3558
+ return "ai-services-ethereum";
3559
+ default:
3560
+ return "ai-services";
3561
+ }
3562
+ }
3563
+ /**
3564
+ * Create a PayAI-compatible performance snapshot
3565
+ * Useful for tracking payment patterns
3566
+ */
3567
+ createPayAIPerformanceSnapshot(record, reputationResult) {
3568
+ return {
3569
+ timestamp: record.timestamp.getTime(),
3570
+ paymentId: record.paymentSignature,
3571
+ network: record.network,
3572
+ amount: record.amount.toString(),
3573
+ success: record.success,
3574
+ responseTimeMs: record.responseTimeMs,
3575
+ reputationChange: reputationResult.jobScore,
3576
+ newScore: reputationResult.overallScore,
3577
+ tier: reputationResult.tier
3578
+ };
3579
+ }
3580
+ // =====================================================
3581
+ // REPUTATION TAGGING METHODS
3582
+ // =====================================================
3583
+ /**
3584
+ * Calculate tags for an agent based on metrics
3585
+ *
3586
+ * Automatically evaluates all tag criteria and assigns tags
3587
+ * with appropriate confidence scores.
3588
+ *
3589
+ * @param metrics - Agent reputation metrics
3590
+ * @returns Array of tag scores
3591
+ */
3592
+ async calculateTagsForAgent(metrics) {
3593
+ return this.tagEngine.calculateTags(metrics);
3594
+ }
3595
+ /**
3596
+ * Get tags by category
3597
+ *
3598
+ * Filters tags to only those in the specified category.
3599
+ *
3600
+ * @param tags - All tag scores
3601
+ * @param category - Category to filter by
3602
+ * @returns Filtered tag scores
3603
+ */
3604
+ getTagsByCategory(tags, category) {
3605
+ return this.tagEngine.filterTags(tags, { category });
3606
+ }
3607
+ /**
3608
+ * Check if agent has a specific tag
3609
+ *
3610
+ * @param tags - Agent's tag scores
3611
+ * @param tagName - Tag to check for
3612
+ * @returns Whether the tag exists
3613
+ */
3614
+ hasTag(tags, tagName) {
3615
+ return tags.some((tag) => tag.tagName === tagName);
3616
+ }
3617
+ /**
3618
+ * Get tag confidence score
3619
+ *
3620
+ * @param tags - Agent's tag scores
3621
+ * @param tagName - Tag to check
3622
+ * @returns Confidence score or undefined if tag doesn't exist
3623
+ */
3624
+ getTagConfidence(tags, tagName) {
3625
+ const tag = tags.find((t) => t.tagName === tagName);
3626
+ return tag?.confidence;
3627
+ }
3628
+ /**
3629
+ * Filter tags by criteria
3630
+ *
3631
+ * @param tags - Tags to filter
3632
+ * @param filters - Filter criteria
3633
+ * @returns Filtered tags
3634
+ */
3635
+ filterTags(tags, filters) {
3636
+ return this.tagEngine.filterTags(tags, filters);
3637
+ }
3638
+ /**
3639
+ * Apply tag decay based on age
3640
+ *
3641
+ * Reduces confidence scores for old tags and removes stale tags.
3642
+ *
3643
+ * @param tags - Current tag scores
3644
+ * @param currentTimestamp - Current Unix timestamp (optional)
3645
+ * @returns Tags with decay applied
3646
+ */
3647
+ applyTagDecay(tags, currentTimestamp) {
3648
+ return this.tagEngine.applyTagDecay(tags, currentTimestamp);
3649
+ }
3650
+ /**
3651
+ * Merge new tags with existing tags
3652
+ *
3653
+ * Updates existing tags or adds new ones, preferring higher confidence.
3654
+ *
3655
+ * @param existingTags - Current tags
3656
+ * @param newTags - New tags to merge
3657
+ * @returns Merged tag list
3658
+ */
3659
+ mergeTags(existingTags, newTags) {
3660
+ return this.tagEngine.mergeTags(existingTags, newTags);
3661
+ }
3662
+ /**
3663
+ * Categorize tags by type
3664
+ *
3665
+ * Organizes tags into skill, behavior, and compliance categories.
3666
+ *
3667
+ * @param tags - Tags to categorize
3668
+ * @returns Categorized tag result
3669
+ */
3670
+ categorizeTags(tags) {
3671
+ return this.tagEngine.categorizeTags(tags);
3672
+ }
3673
+ /**
3674
+ * Get top N tags by confidence
3675
+ *
3676
+ * @param tags - Tags to sort
3677
+ * @param count - Number of tags to return
3678
+ * @returns Top tags
3679
+ */
3680
+ getTopTags(tags, count) {
3681
+ return this.tagEngine.getTopTags(tags, count);
3682
+ }
3683
+ /**
3684
+ * Sort tags by confidence (descending)
3685
+ *
3686
+ * @param tags - Tags to sort
3687
+ * @returns Sorted tags
3688
+ */
3689
+ sortTagsByConfidence(tags) {
3690
+ return this.tagEngine.sortByConfidence(tags);
3691
+ }
3692
+ /**
3693
+ * Sort tags by evidence count (descending)
3694
+ *
3695
+ * @param tags - Tags to sort
3696
+ * @returns Sorted tags
3697
+ */
3698
+ sortTagsByEvidence(tags) {
3699
+ return this.tagEngine.sortByEvidence(tags);
3700
+ }
3701
+ /**
3702
+ * Sort tags by most recently updated
3703
+ *
3704
+ * @param tags - Tags to sort
3705
+ * @returns Sorted tags
3706
+ */
3707
+ sortTagsByRecent(tags) {
3708
+ return this.tagEngine.sortByRecent(tags);
3709
+ }
3710
+ /**
3711
+ * Get confidence level description
3712
+ *
3713
+ * @param confidence - Confidence score (0-10000)
3714
+ * @returns Human-readable confidence level
3715
+ */
3716
+ getConfidenceLevel(confidence) {
3717
+ return this.tagEngine.getConfidenceLevel(confidence);
3718
+ }
3719
+ /**
3720
+ * Validate tag name length
3721
+ *
3722
+ * @param tagName - Tag name to validate
3723
+ * @returns Whether tag name is valid
3724
+ */
3725
+ validateTagName(tagName) {
3726
+ return this.tagEngine.validateTagName(tagName);
3727
+ }
3728
+ /**
3729
+ * Validate confidence score
3730
+ *
3731
+ * @param confidence - Confidence to validate
3732
+ * @returns Whether confidence is valid (0-10000)
3733
+ */
3734
+ validateConfidence(confidence) {
3735
+ return this.tagEngine.validateConfidence(confidence);
3736
+ }
3737
+ /**
3738
+ * Convert on-chain ReputationMetrics to TagEngine format
3739
+ *
3740
+ * Helper to convert blockchain data to the format needed for tag calculation.
3741
+ *
3742
+ * @param onChainMetrics - Metrics from blockchain
3743
+ * @returns Metrics in TagEngine format
3744
+ */
3745
+ convertMetricsForTagging(onChainMetrics) {
3746
+ const avgResponseTime = onChainMetrics.responseTimeCount > 0n ? Number(onChainMetrics.totalResponseTime / onChainMetrics.responseTimeCount) : 0;
3747
+ const totalPayments = onChainMetrics.successfulPayments + onChainMetrics.failedPayments;
3748
+ const successRate = totalPayments > 0n ? Number(onChainMetrics.successfulPayments * 10000n / totalPayments) : 0;
3749
+ const avgRating = onChainMetrics.totalRatingsCount > 0 ? Math.floor(
3750
+ onChainMetrics.totalRating * 100 / (onChainMetrics.totalRatingsCount * 5)
3751
+ ) : 0;
3752
+ const disputeResolutionRate = onChainMetrics.totalDisputes > 0 ? Math.floor(onChainMetrics.disputesResolved * 1e4 / onChainMetrics.totalDisputes) : 1e4;
3753
+ return {
3754
+ successfulPayments: onChainMetrics.successfulPayments,
3755
+ failedPayments: onChainMetrics.failedPayments,
3756
+ totalResponseTime: onChainMetrics.totalResponseTime,
3757
+ responseTimeCount: onChainMetrics.responseTimeCount,
3758
+ totalDisputes: onChainMetrics.totalDisputes,
3759
+ disputesResolved: onChainMetrics.disputesResolved,
3760
+ totalRating: onChainMetrics.totalRating,
3761
+ totalRatingsCount: onChainMetrics.totalRatingsCount,
3762
+ createdAt: onChainMetrics.createdAt,
3763
+ updatedAt: onChainMetrics.updatedAt,
3764
+ avgResponseTime,
3765
+ successRate,
3766
+ avgRating,
3767
+ disputeResolutionRate
3768
+ };
3769
+ }
3770
+ };
3771
+
3772
+ // src/modules/staking/StakingModule.ts
3773
+ var StakingModule = class extends BaseModule {
3774
+ /**
3775
+ * Initialize the global staking configuration (admin only)
3776
+ */
3777
+ async initializeStakingConfig(params) {
3778
+ const instruction = await getInitializeStakingConfigInstructionAsync({
3779
+ authority: params.authority,
3780
+ minStake: params.minStake,
3781
+ treasury: params.treasury
3782
+ }, { programAddress: this.programId });
3783
+ return this.execute("initializeStakingConfig", () => instruction, [params.authority]);
3784
+ }
3785
+ /**
3786
+ * Stake GHOST tokens for an agent
3787
+ *
3788
+ * @param params - Staking parameters
3789
+ * @returns Transaction signature
3790
+ */
3791
+ async stake(params) {
3792
+ const instruction = await getStakeGhostInstructionAsync({
3793
+ ownerTokenAccount: params.agentTokenAccount,
3794
+ stakingVault: params.stakingVault,
3795
+ stakingConfig: params.stakingConfig,
3796
+ ghostMint: params.ghostMint,
3797
+ owner: params.agentOwner,
3798
+ amount: params.amount,
3799
+ lockDuration: params.lockDuration
3800
+ }, { programAddress: this.programId });
3801
+ return this.execute("stakeGhost", () => instruction, [params.agentOwner]);
3802
+ }
3803
+ /**
3804
+ * Unstake GHOST tokens from an agent
3805
+ *
3806
+ * @param params - Unstaking parameters
3807
+ * @returns Transaction signature
3808
+ */
3809
+ async unstake(params) {
3810
+ const instruction = await getUnstakeGhostInstructionAsync({
3811
+ stakingAccount: params.stakingAccount,
3812
+ stakingVault: params.stakingVault,
3813
+ ownerTokenAccount: params.agentTokenAccount,
3814
+ owner: params.agentOwner
3815
+ }, { programAddress: this.programId });
3816
+ return this.execute("unstakeGhost", () => instruction, [params.agentOwner]);
3817
+ }
3818
+ /**
3819
+ * Get staking account for an agent
3820
+ *
3821
+ * @param stakingAccountAddress - The staking account address
3822
+ * @returns Staking account data or null if not found
3823
+ */
3824
+ async getStakingAccount(stakingAccountAddress) {
3825
+ try {
3826
+ return await this.getAccount(stakingAccountAddress, "getStakingAccountDecoder");
3827
+ } catch (error) {
3828
+ console.error("Error fetching staking account:", error);
3829
+ return null;
3830
+ }
3831
+ }
3832
+ /**
3833
+ * Get the global staking configuration
3834
+ *
3835
+ * @param stakingConfigAddress - The staking config account address
3836
+ * @returns Staking config data or null if not initialized
3837
+ */
3838
+ async getStakingConfig(stakingConfigAddress) {
3839
+ try {
3840
+ return await this.getAccount(stakingConfigAddress, "getStakingConfigDecoder");
3841
+ } catch (error) {
3842
+ console.error("Error fetching staking config:", error);
3843
+ return null;
3844
+ }
3845
+ }
3846
+ };
3847
+
3848
+ export { ATTESTATION_SEED, AgentModule, BaseModule, CREDENTIAL_SEED, CacheManager, CredentialKind, CredentialModule, CredentialStatus, DEFAULT_IPFS_CONFIG, DidError, DidErrorClass, GhostModule, GovernanceModule, IPFSUtils, InstructionBuilder, MultiSourceAggregator, MultiSourceAggregator_exports, MultisigModule, ReputationModule, RpcClient, SASAttestationHelper, SAS_PROGRAM_ID, SCHEMA_SEED, ServiceEndpointType, StakingModule, VerificationMethodType, VerificationRelationship, canPerformAction, createEd25519VerificationMethod, createIPFSUtils, createMetadataUri, createServiceEndpoint, deriveDidDocumentPda, determineStorageMethod, didDocumentToJson, exportAsW3CDidDocument, generateDidString, getIdentifierFromDid, getMethodsForRelationship, getNetworkFromDid, init_MultiSourceAggregator, isDidActive, parseDidString, validateDidString };
3849
+ //# sourceMappingURL=chunk-JYXSOXCP.js.map
3850
+ //# sourceMappingURL=chunk-JYXSOXCP.js.map