@ghostspeak/sdk 2.0.7 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/{GhostSpeakClient-CWmGaM9Q.d.ts → GhostSpeakClient-qdLGyuDp.d.ts} +11 -7
- package/dist/{StakingModule-C5rzuOWb.d.ts → StakingModule-CPhp_ZY0.d.ts} +263 -343
- package/dist/{agent-5YLZ7DAC.js → agent-S42FIMR7.js} +3 -3
- package/dist/{agent-5YLZ7DAC.js.map → agent-S42FIMR7.js.map} +1 -1
- package/dist/browser-D1TpjbjZ.d.ts +234 -0
- package/dist/browser.d.ts +4 -64
- package/dist/browser.js +9 -9
- package/dist/{chunk-SFTSZ3LC.js → chunk-46QWY3MG.js} +3 -3
- package/dist/{chunk-SFTSZ3LC.js.map → chunk-46QWY3MG.js.map} +1 -1
- package/dist/{chunk-IHVDQ4YI.js → chunk-5QZVFUXB.js} +201 -256
- package/dist/chunk-5QZVFUXB.js.map +1 -0
- package/dist/{chunk-E3FD2CNY.js → chunk-5SS3OL4B.js} +20 -24
- package/dist/chunk-5SS3OL4B.js.map +1 -0
- package/dist/{chunk-SZGFSCNU.js → chunk-63A7F2YP.js} +504 -326
- package/dist/chunk-63A7F2YP.js.map +1 -0
- package/dist/{chunk-JV2SWONF.js → chunk-A7ALCVUI.js} +3 -3
- package/dist/{chunk-JV2SWONF.js.map → chunk-A7ALCVUI.js.map} +1 -1
- package/dist/{chunk-AL3HQN73.js → chunk-AWMGX3OX.js} +172 -112
- package/dist/chunk-AWMGX3OX.js.map +1 -0
- package/dist/{chunk-G7S6B6WB.js → chunk-EU6PHSM5.js} +7 -7
- package/dist/{chunk-G7S6B6WB.js.map → chunk-EU6PHSM5.js.map} +1 -1
- package/dist/{chunk-C5CDA3WX.js → chunk-HIDBANFS.js} +529 -4
- package/dist/chunk-HIDBANFS.js.map +1 -0
- package/dist/{chunk-S74EH3KD.js → chunk-IQM5RASO.js} +637 -25
- package/dist/chunk-IQM5RASO.js.map +1 -0
- package/dist/{chunk-KB6CKIUK.js → chunk-QLRWUHN2.js} +3 -3
- package/dist/{chunk-KB6CKIUK.js.map → chunk-QLRWUHN2.js.map} +1 -1
- package/dist/{chunk-BQDGRTVP.js → chunk-QWQTPTZ4.js} +39 -51
- package/dist/chunk-QWQTPTZ4.js.map +1 -0
- package/dist/client.d.ts +3 -4
- package/dist/client.js +10 -10
- package/dist/{createAgentAuthorization-ULG47ZJI.js → createAgentAuthorization-KGZNXZBT.js} +4 -4
- package/dist/{createAgentAuthorization-ULG47ZJI.js.map → createAgentAuthorization-KGZNXZBT.js.map} +1 -1
- package/dist/generated-QJREJQ2C.js +9 -0
- package/dist/{generated-EG5USUFG.js.map → generated-QJREJQ2C.js.map} +1 -1
- package/dist/index.d.ts +345 -236
- package/dist/index.js +372 -537
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/minimal/core-minimal.d.ts +266 -189
- package/dist/minimal/core-minimal.js +6 -6
- package/dist/minimal/core-minimal.js.map +1 -1
- package/dist/{revokeAuthorization-OK7E7OK3.js → revokeAuthorization-2ZRO6GUZ.js} +4 -4
- package/dist/{revokeAuthorization-OK7E7OK3.js.map → revokeAuthorization-2ZRO6GUZ.js.map} +1 -1
- package/dist/{signature-verification-DGxR4aYQ.d.ts → signature-verification-BDzoR1MG.d.ts} +0 -5
- package/dist/{updateReputationWithAuth-Y4ONEVSP.js → updateReputationWithAuth-PCEUOCFV.js} +4 -4
- package/dist/{updateReputationWithAuth-Y4ONEVSP.js.map → updateReputationWithAuth-PCEUOCFV.js.map} +1 -1
- package/dist/utils.d.ts +143 -2
- package/dist/utils.js +10 -10
- package/dist/utils.js.map +1 -1
- package/package.json +5 -3
- package/dist/chunk-AL3HQN73.js.map +0 -1
- package/dist/chunk-BQDGRTVP.js.map +0 -1
- package/dist/chunk-C5CDA3WX.js.map +0 -1
- package/dist/chunk-E3FD2CNY.js.map +0 -1
- package/dist/chunk-IHVDQ4YI.js.map +0 -1
- package/dist/chunk-S74EH3KD.js.map +0 -1
- package/dist/chunk-SZGFSCNU.js.map +0 -1
- package/dist/generated-EG5USUFG.js +0 -9
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { init_reputation_tag_engine, createErrorContext, logEnhancedError, IPFSClient, SYSTEM_PROGRAM_ADDRESS, ReputationCalculator, ReputationTagEngine, REPUTATION_CONSTANTS } from './chunk-
|
|
2
|
-
import { getInitializeGovernanceProposalInstructionAsync, getInitializeStakingConfigInstructionAsync, getStakeGhostInstructionAsync, getUnstakeGhostInstructionAsync, getRegisterAgentInstructionAsync, getRegisterAgentCompressedInstructionAsync, getUpdateAgentInstruction, getVerifyAgentInstructionAsync, getDeactivateAgentInstruction, getActivateAgentInstruction } from './chunk-
|
|
1
|
+
import { init_reputation_tag_engine, createSolanaClient, createErrorContext, logEnhancedError, IPFSClient, SYSTEM_PROGRAM_ADDRESS, ReputationCalculator, ReputationTagEngine, REPUTATION_CONSTANTS } from './chunk-HIDBANFS.js';
|
|
2
|
+
import { getInitializeGovernanceProposalInstructionAsync, getInitializeStakingConfigInstructionAsync, getStakeGhostInstructionAsync, getUnstakeGhostInstructionAsync, getRegisterAgentInstructionAsync, getRegisterAgentCompressedInstructionAsync, getUpdateAgentInstruction, getVerifyAgentInstructionAsync, getDeactivateAgentInstruction, getActivateAgentInstruction, getClaimGhostInstruction } from './chunk-IQM5RASO.js';
|
|
3
3
|
import { __export, __esm } from './chunk-UP2VWCW5.js';
|
|
4
|
-
import {
|
|
4
|
+
import { lamports, pipe, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, signTransactionMessageWithSigners, setTransactionMessageFeePayer, compileTransactionMessage, getBase64EncodedWireTransaction, getProgramDerivedAddress, getUtf8Encoder, getAddressEncoder } from '@solana/kit';
|
|
5
5
|
import { LRUCache } from 'lru-cache';
|
|
6
|
+
import { address } from '@solana/addresses';
|
|
6
7
|
import bs58 from 'bs58';
|
|
7
8
|
import { sha256 } from '@noble/hashes/sha256';
|
|
8
|
-
import { EventEmitter } from 'events';
|
|
9
9
|
|
|
10
10
|
// src/modules/reputation/MultiSourceAggregator.ts
|
|
11
11
|
var MultiSourceAggregator_exports = {};
|
|
@@ -261,8 +261,7 @@ var init_MultiSourceAggregator = __esm({
|
|
|
261
261
|
}
|
|
262
262
|
});
|
|
263
263
|
var RpcClient = class {
|
|
264
|
-
|
|
265
|
-
rpcSubscriptions;
|
|
264
|
+
client;
|
|
266
265
|
commitment;
|
|
267
266
|
endpoint;
|
|
268
267
|
maxRetries;
|
|
@@ -270,21 +269,25 @@ var RpcClient = class {
|
|
|
270
269
|
timeout;
|
|
271
270
|
constructor(config) {
|
|
272
271
|
this.endpoint = config.endpoint;
|
|
273
|
-
this.
|
|
272
|
+
this.client = createSolanaClient({ urlOrMoniker: config.endpoint });
|
|
274
273
|
this.commitment = config.commitment ?? "confirmed";
|
|
275
274
|
this.maxRetries = config.maxRetries ?? 3;
|
|
276
275
|
this.retryDelay = config.retryDelay ?? 1e3;
|
|
277
276
|
this.timeout = config.timeout ?? 6e4;
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Get the underlying RPC client for direct access
|
|
280
|
+
* This provides access to Gill's rpc object for advanced operations
|
|
281
|
+
*/
|
|
282
|
+
get rpc() {
|
|
283
|
+
return this.client.rpc;
|
|
281
284
|
}
|
|
282
285
|
/**
|
|
283
286
|
* Get account information with automatic retries
|
|
284
287
|
*/
|
|
285
|
-
async getAccountInfo(
|
|
288
|
+
async getAccountInfo(address2, options) {
|
|
286
289
|
return this.withRetry(async () => {
|
|
287
|
-
const result = await this.rpc.getAccountInfo(
|
|
290
|
+
const result = await this.client.rpc.getAccountInfo(address2, {
|
|
288
291
|
commitment: options?.commitment ?? this.commitment,
|
|
289
292
|
encoding: "base64"
|
|
290
293
|
}).send();
|
|
@@ -297,7 +300,7 @@ var RpcClient = class {
|
|
|
297
300
|
*/
|
|
298
301
|
async getMultipleAccounts(addresses, options) {
|
|
299
302
|
return this.withRetry(async () => {
|
|
300
|
-
const result = await this.rpc.getMultipleAccounts(addresses, {
|
|
303
|
+
const result = await this.client.rpc.getMultipleAccounts(addresses, {
|
|
301
304
|
commitment: options?.commitment ?? this.commitment,
|
|
302
305
|
encoding: "base64"
|
|
303
306
|
}).send();
|
|
@@ -311,7 +314,7 @@ var RpcClient = class {
|
|
|
311
314
|
*/
|
|
312
315
|
async getProgramAccounts(programId, options) {
|
|
313
316
|
return this.withRetry(async () => {
|
|
314
|
-
const result = await this.rpc.getProgramAccounts(programId, {
|
|
317
|
+
const result = await this.client.rpc.getProgramAccounts(programId, {
|
|
315
318
|
commitment: options?.commitment ?? this.commitment,
|
|
316
319
|
encoding: "base64",
|
|
317
320
|
filters: options?.filters
|
|
@@ -335,7 +338,7 @@ var RpcClient = class {
|
|
|
335
338
|
return this.blockhashCache.value;
|
|
336
339
|
}
|
|
337
340
|
const result = await this.withRetry(async () => {
|
|
338
|
-
const response = await this.rpc.getLatestBlockhash({
|
|
341
|
+
const response = await this.client.rpc.getLatestBlockhash({
|
|
339
342
|
commitment: this.commitment
|
|
340
343
|
}).send();
|
|
341
344
|
return {
|
|
@@ -351,7 +354,7 @@ var RpcClient = class {
|
|
|
351
354
|
*/
|
|
352
355
|
async sendTransaction(transaction, options) {
|
|
353
356
|
return this.withRetry(async () => {
|
|
354
|
-
const result = await this.rpc.sendTransaction(transaction, {
|
|
357
|
+
const result = await this.client.rpc.sendTransaction(transaction, {
|
|
355
358
|
encoding: "base64",
|
|
356
359
|
skipPreflight: options?.skipPreflight ?? false,
|
|
357
360
|
preflightCommitment: options?.preflightCommitment ?? this.commitment,
|
|
@@ -365,7 +368,7 @@ var RpcClient = class {
|
|
|
365
368
|
*/
|
|
366
369
|
async getSignatureStatuses(signatures) {
|
|
367
370
|
return this.withRetry(async () => {
|
|
368
|
-
const result = await this.rpc.getSignatureStatuses(signatures).send();
|
|
371
|
+
const result = await this.client.rpc.getSignatureStatuses(signatures).send();
|
|
369
372
|
return result.value.map((status) => {
|
|
370
373
|
if (!status) return null;
|
|
371
374
|
const typedStatus = status;
|
|
@@ -383,7 +386,7 @@ var RpcClient = class {
|
|
|
383
386
|
*/
|
|
384
387
|
async simulateTransaction(transaction, options) {
|
|
385
388
|
return this.withRetry(async () => {
|
|
386
|
-
const result = await this.rpc.simulateTransaction(transaction, {
|
|
389
|
+
const result = await this.client.rpc.simulateTransaction(transaction, {
|
|
387
390
|
encoding: "base64",
|
|
388
391
|
commitment: options?.commitment ?? this.commitment,
|
|
389
392
|
replaceRecentBlockhash: options?.replaceRecentBlockhash ?? false
|
|
@@ -401,7 +404,7 @@ var RpcClient = class {
|
|
|
401
404
|
*/
|
|
402
405
|
async getFeeForMessage(encodedMessage) {
|
|
403
406
|
return this.withRetry(async () => {
|
|
404
|
-
const result = await this.rpc.getFeeForMessage(encodedMessage, {
|
|
407
|
+
const result = await this.client.rpc.getFeeForMessage(encodedMessage, {
|
|
405
408
|
commitment: this.commitment
|
|
406
409
|
}).send();
|
|
407
410
|
return result.value ? BigInt(result.value) : null;
|
|
@@ -412,7 +415,7 @@ var RpcClient = class {
|
|
|
412
415
|
*/
|
|
413
416
|
async isHealthy() {
|
|
414
417
|
try {
|
|
415
|
-
await this.rpc.getHealth().send();
|
|
418
|
+
await this.client.rpc.getHealth().send();
|
|
416
419
|
return true;
|
|
417
420
|
} catch {
|
|
418
421
|
return false;
|
|
@@ -422,21 +425,21 @@ var RpcClient = class {
|
|
|
422
425
|
* Get RPC node version
|
|
423
426
|
*/
|
|
424
427
|
async getVersion() {
|
|
425
|
-
const result = await this.rpc.getVersion().send();
|
|
428
|
+
const result = await this.client.rpc.getVersion().send();
|
|
426
429
|
return result;
|
|
427
430
|
}
|
|
428
431
|
/**
|
|
429
|
-
* Subscribe to account changes (WebSocket)
|
|
430
|
-
*
|
|
432
|
+
* Subscribe to account changes (WebSocket)
|
|
433
|
+
*
|
|
434
|
+
* Note: This is a polling-based implementation for backward compatibility.
|
|
435
|
+
* For production use with real-time subscriptions, access the rpcSubscriptions
|
|
436
|
+
* directly via client.rpcSubscriptions from Gill.
|
|
431
437
|
*/
|
|
432
|
-
async subscribeToAccount(
|
|
433
|
-
|
|
434
|
-
throw new Error("WebSocket endpoint not configured");
|
|
435
|
-
}
|
|
436
|
-
console.warn("Account subscription is not fully implemented in this version");
|
|
438
|
+
async subscribeToAccount(address2, callback) {
|
|
439
|
+
console.warn("Account subscription using polling fallback. For real-time subscriptions, use client.rpcSubscriptions directly.");
|
|
437
440
|
const intervalId = setInterval(async () => {
|
|
438
441
|
try {
|
|
439
|
-
const accountInfo = await this.getAccountInfo(
|
|
442
|
+
const accountInfo = await this.getAccountInfo(address2);
|
|
440
443
|
callback(accountInfo);
|
|
441
444
|
} catch (error) {
|
|
442
445
|
console.error("Subscription polling error:", error);
|
|
@@ -446,6 +449,15 @@ var RpcClient = class {
|
|
|
446
449
|
clearInterval(intervalId);
|
|
447
450
|
};
|
|
448
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* Get the underlying Gill client for advanced operations
|
|
454
|
+
* This provides direct access to Gill's SolanaClient for features like:
|
|
455
|
+
* - rpcSubscriptions for WebSocket subscriptions
|
|
456
|
+
* - sendAndConfirmTransaction for transaction handling
|
|
457
|
+
*/
|
|
458
|
+
getGillClient() {
|
|
459
|
+
return this.client;
|
|
460
|
+
}
|
|
449
461
|
// Private helper methods
|
|
450
462
|
async withRetry(operation, retries = this.maxRetries) {
|
|
451
463
|
let lastError;
|
|
@@ -946,19 +958,19 @@ var InstructionBuilder = class {
|
|
|
946
958
|
/**
|
|
947
959
|
* Get and decode account data with unified error handling
|
|
948
960
|
*/
|
|
949
|
-
async getAccount(
|
|
961
|
+
async getAccount(address2, decoderImportName) {
|
|
950
962
|
try {
|
|
951
|
-
const accountInfo = await this.rpcClient.getAccountInfo(
|
|
963
|
+
const accountInfo = await this.rpcClient.getAccountInfo(address2, {
|
|
952
964
|
commitment: this.config.commitment
|
|
953
965
|
});
|
|
954
966
|
if (!accountInfo) return null;
|
|
955
|
-
const generated = await import('./generated-
|
|
967
|
+
const generated = await import('./generated-QJREJQ2C.js');
|
|
956
968
|
const decoderGetter = generated[decoderImportName];
|
|
957
969
|
const decoder = decoderGetter();
|
|
958
970
|
const rawData = this.extractRawData(accountInfo.data);
|
|
959
971
|
return decoder.decode(rawData);
|
|
960
972
|
} catch (error) {
|
|
961
|
-
console.warn(`Failed to fetch account ${
|
|
973
|
+
console.warn(`Failed to fetch account ${address2}:`, error);
|
|
962
974
|
return null;
|
|
963
975
|
}
|
|
964
976
|
}
|
|
@@ -970,7 +982,7 @@ var InstructionBuilder = class {
|
|
|
970
982
|
const accounts = await this.rpcClient.getMultipleAccounts(addresses, {
|
|
971
983
|
commitment: this.config.commitment
|
|
972
984
|
});
|
|
973
|
-
const generated = await import('./generated-
|
|
985
|
+
const generated = await import('./generated-QJREJQ2C.js');
|
|
974
986
|
const decoderGetter = generated[decoderImportName];
|
|
975
987
|
const decoder = decoderGetter();
|
|
976
988
|
return accounts.map((accountInfo) => {
|
|
@@ -1020,7 +1032,7 @@ var InstructionBuilder = class {
|
|
|
1020
1032
|
commitment: this.config.commitment,
|
|
1021
1033
|
filters: convertedFilters ?? []
|
|
1022
1034
|
});
|
|
1023
|
-
const generated = await import('./generated-
|
|
1035
|
+
const generated = await import('./generated-QJREJQ2C.js');
|
|
1024
1036
|
const decoderGetter = generated[decoderImportName];
|
|
1025
1037
|
const decoder = decoderGetter();
|
|
1026
1038
|
const decodedAccounts = [];
|
|
@@ -1148,9 +1160,8 @@ var InstructionBuilder = class {
|
|
|
1148
1160
|
} else {
|
|
1149
1161
|
console.log("\u{1F50D} No status found, trying transaction details...");
|
|
1150
1162
|
try {
|
|
1151
|
-
const {
|
|
1152
|
-
const
|
|
1153
|
-
const transaction = await directRpc.getTransaction(signature, {
|
|
1163
|
+
const directClient = createSolanaClient({ urlOrMoniker: this.config.rpcEndpoint ?? "https://api.devnet.solana.com" });
|
|
1164
|
+
const transaction = await directClient.rpc.getTransaction(signature, {
|
|
1154
1165
|
commitment: this.config.commitment ?? "confirmed",
|
|
1155
1166
|
encoding: "json",
|
|
1156
1167
|
maxSupportedTransactionVersion: 0
|
|
@@ -1182,9 +1193,8 @@ var InstructionBuilder = class {
|
|
|
1182
1193
|
if (!confirmed) {
|
|
1183
1194
|
console.log("\u{1F50D} Final confirmation attempt via transaction lookup...");
|
|
1184
1195
|
try {
|
|
1185
|
-
const {
|
|
1186
|
-
const
|
|
1187
|
-
const transaction = await directRpc.getTransaction(signature, {
|
|
1196
|
+
const directClient = createSolanaClient({ urlOrMoniker: this.config.rpcEndpoint ?? "https://api.devnet.solana.com" });
|
|
1197
|
+
const transaction = await directClient.rpc.getTransaction(signature, {
|
|
1188
1198
|
commitment: this.config.commitment ?? "confirmed",
|
|
1189
1199
|
encoding: "json",
|
|
1190
1200
|
maxSupportedTransactionVersion: 0
|
|
@@ -1348,9 +1358,9 @@ var CacheManager = class {
|
|
|
1348
1358
|
* @param currentSlot - Current blockchain slot (for staleness check)
|
|
1349
1359
|
* @returns Cached data or undefined
|
|
1350
1360
|
*/
|
|
1351
|
-
getAccount(
|
|
1361
|
+
getAccount(address2, commitment, currentSlot) {
|
|
1352
1362
|
if (!this.config.enabled) return void 0;
|
|
1353
|
-
const key = `${
|
|
1363
|
+
const key = `${address2}:${commitment}`;
|
|
1354
1364
|
const entry = this.accountCache.get(key);
|
|
1355
1365
|
if (!entry) return void 0;
|
|
1356
1366
|
if (currentSlot !== void 0 && entry.slot < currentSlot) {
|
|
@@ -1367,9 +1377,9 @@ var CacheManager = class {
|
|
|
1367
1377
|
* @param commitment - Commitment level
|
|
1368
1378
|
* @param slot - Blockchain slot when data was fetched
|
|
1369
1379
|
*/
|
|
1370
|
-
setAccount(
|
|
1380
|
+
setAccount(address2, data, commitment, slot) {
|
|
1371
1381
|
if (!this.config.enabled) return;
|
|
1372
|
-
const key = `${
|
|
1382
|
+
const key = `${address2}:${commitment}`;
|
|
1373
1383
|
const entry = {
|
|
1374
1384
|
data,
|
|
1375
1385
|
slot,
|
|
@@ -1408,13 +1418,13 @@ var CacheManager = class {
|
|
|
1408
1418
|
* @param address - Account address to invalidate
|
|
1409
1419
|
* @param commitment - Optional commitment level (invalidates all if not specified)
|
|
1410
1420
|
*/
|
|
1411
|
-
invalidateAccount(
|
|
1421
|
+
invalidateAccount(address2, commitment) {
|
|
1412
1422
|
if (!this.config.enabled) return;
|
|
1413
1423
|
if (commitment) {
|
|
1414
|
-
this.accountCache.delete(`${
|
|
1424
|
+
this.accountCache.delete(`${address2}:${commitment}`);
|
|
1415
1425
|
} else {
|
|
1416
1426
|
["processed", "confirmed", "finalized"].forEach((c) => {
|
|
1417
|
-
this.accountCache.delete(`${
|
|
1427
|
+
this.accountCache.delete(`${address2}:${c}`);
|
|
1418
1428
|
});
|
|
1419
1429
|
}
|
|
1420
1430
|
}
|
|
@@ -1540,19 +1550,19 @@ var BaseModule = class {
|
|
|
1540
1550
|
/**
|
|
1541
1551
|
* Get decoded account (with optional caching)
|
|
1542
1552
|
*/
|
|
1543
|
-
async getAccount(
|
|
1553
|
+
async getAccount(address2, decoderImportName) {
|
|
1544
1554
|
if (this.cacheManager.isEnabled()) {
|
|
1545
|
-
const cached = this.cacheManager.getAccount(
|
|
1555
|
+
const cached = this.cacheManager.getAccount(address2, this.commitment);
|
|
1546
1556
|
if (cached !== void 0) {
|
|
1547
|
-
this.logger?.info(`[Cache HIT] ${
|
|
1557
|
+
this.logger?.info(`[Cache HIT] ${address2}`);
|
|
1548
1558
|
return cached;
|
|
1549
1559
|
}
|
|
1550
1560
|
}
|
|
1551
|
-
const account = await this.builder.getAccount(
|
|
1561
|
+
const account = await this.builder.getAccount(address2, decoderImportName);
|
|
1552
1562
|
if (this.cacheManager.isEnabled() && account !== null) {
|
|
1553
1563
|
const slot = 0;
|
|
1554
|
-
this.cacheManager.setAccount(
|
|
1555
|
-
this.logger?.info(`[Cache SET] ${
|
|
1564
|
+
this.cacheManager.setAccount(address2, account, this.commitment, slot);
|
|
1565
|
+
this.logger?.info(`[Cache SET] ${address2}`);
|
|
1556
1566
|
}
|
|
1557
1567
|
return account;
|
|
1558
1568
|
}
|
|
@@ -1624,9 +1634,9 @@ var BaseModule = class {
|
|
|
1624
1634
|
/**
|
|
1625
1635
|
* Invalidate cache for specific account
|
|
1626
1636
|
*/
|
|
1627
|
-
invalidateCache(
|
|
1628
|
-
this.cacheManager.invalidateAccount(
|
|
1629
|
-
this.logger?.info(`[Cache INVALIDATE] ${
|
|
1637
|
+
invalidateCache(address2) {
|
|
1638
|
+
this.cacheManager.invalidateAccount(address2);
|
|
1639
|
+
this.logger?.info(`[Cache INVALIDATE] ${address2}`);
|
|
1630
1640
|
}
|
|
1631
1641
|
/**
|
|
1632
1642
|
* Clear all caches
|
|
@@ -2147,8 +2157,8 @@ var AgentModule = class extends BaseModule {
|
|
|
2147
2157
|
/**
|
|
2148
2158
|
* Get agent account
|
|
2149
2159
|
*/
|
|
2150
|
-
async getAgentAccount(
|
|
2151
|
-
return super.getAccount(
|
|
2160
|
+
async getAgentAccount(address2) {
|
|
2161
|
+
return super.getAccount(address2, "getAgentDecoder");
|
|
2152
2162
|
}
|
|
2153
2163
|
/**
|
|
2154
2164
|
* Get all agents
|
|
@@ -2262,18 +2272,18 @@ var AgentModule = class extends BaseModule {
|
|
|
2262
2272
|
// Helper methods
|
|
2263
2273
|
async deriveAgentPda(agentId, owner) {
|
|
2264
2274
|
const { deriveAgentPda } = await import('./pda-4KP7CURF.js');
|
|
2265
|
-
const [
|
|
2266
|
-
return
|
|
2275
|
+
const [address2] = await deriveAgentPda({ programAddress: this.programId, owner, agentId });
|
|
2276
|
+
return address2;
|
|
2267
2277
|
}
|
|
2268
2278
|
async deriveUserRegistryPda(owner) {
|
|
2269
2279
|
const { deriveUserRegistryPda } = await import('./pda-4KP7CURF.js');
|
|
2270
2280
|
return deriveUserRegistryPda(this.programId, owner);
|
|
2271
2281
|
}
|
|
2272
2282
|
async deriveTreeConfigPda(owner) {
|
|
2273
|
-
const { getProgramDerivedAddress:
|
|
2274
|
-
const addressEncoder =
|
|
2283
|
+
const { getProgramDerivedAddress: getProgramDerivedAddress4, getAddressEncoder: getAddressEncoder4 } = await import('@solana/addresses');
|
|
2284
|
+
const addressEncoder = getAddressEncoder4();
|
|
2275
2285
|
const ownerBytes = addressEncoder.encode(owner);
|
|
2276
|
-
const [pda] = await
|
|
2286
|
+
const [pda] = await getProgramDerivedAddress4({
|
|
2277
2287
|
programAddress: this.programId,
|
|
2278
2288
|
seeds: [
|
|
2279
2289
|
new TextEncoder().encode("agent_tree_config"),
|
|
@@ -2289,6 +2299,427 @@ var AgentModule = class extends BaseModule {
|
|
|
2289
2299
|
return "cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK";
|
|
2290
2300
|
}
|
|
2291
2301
|
};
|
|
2302
|
+
var SAS_PROGRAM_ID = address("22zoJMtdu4tQc2PzL74ZUT7FrwgB1Udec8DdW4yw4BdG");
|
|
2303
|
+
var ATTESTATION_SEED = "attestation";
|
|
2304
|
+
var CREDENTIAL_SEED = "credential";
|
|
2305
|
+
var SCHEMA_SEED = "schema";
|
|
2306
|
+
var SASAttestationHelper = class {
|
|
2307
|
+
/**
|
|
2308
|
+
* Derive attestation PDA for a given credential, schema, and nonce
|
|
2309
|
+
*
|
|
2310
|
+
* PDA seeds: ["attestation", credential, schema, nonce]
|
|
2311
|
+
*
|
|
2312
|
+
* @param credentialAddress - SAS Credential address (issuer)
|
|
2313
|
+
* @param schemaAddress - SAS Schema address (defines structure)
|
|
2314
|
+
* @param nonce - Unique nonce (typically the x402_payment_address)
|
|
2315
|
+
* @returns Attestation PDA and bump
|
|
2316
|
+
*/
|
|
2317
|
+
static async deriveAttestationPda(credentialAddress, schemaAddress, nonce) {
|
|
2318
|
+
const [pda, bump] = await getProgramDerivedAddress({
|
|
2319
|
+
programAddress: SAS_PROGRAM_ID,
|
|
2320
|
+
seeds: [
|
|
2321
|
+
getUtf8Encoder().encode(ATTESTATION_SEED),
|
|
2322
|
+
getAddressEncoder().encode(credentialAddress),
|
|
2323
|
+
getAddressEncoder().encode(schemaAddress),
|
|
2324
|
+
getAddressEncoder().encode(nonce)
|
|
2325
|
+
]
|
|
2326
|
+
});
|
|
2327
|
+
return {
|
|
2328
|
+
attestationPda: pda,
|
|
2329
|
+
bump
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
/**
|
|
2333
|
+
* Derive credential PDA for an issuer
|
|
2334
|
+
*
|
|
2335
|
+
* PDA seeds: ["credential", issuer]
|
|
2336
|
+
*
|
|
2337
|
+
* @param issuer - Issuer's public key
|
|
2338
|
+
* @returns Credential PDA and bump
|
|
2339
|
+
*/
|
|
2340
|
+
static async deriveCredentialPda(issuer) {
|
|
2341
|
+
const [pda, bump] = await getProgramDerivedAddress({
|
|
2342
|
+
programAddress: SAS_PROGRAM_ID,
|
|
2343
|
+
seeds: [
|
|
2344
|
+
getUtf8Encoder().encode(CREDENTIAL_SEED),
|
|
2345
|
+
getAddressEncoder().encode(issuer)
|
|
2346
|
+
]
|
|
2347
|
+
});
|
|
2348
|
+
return {
|
|
2349
|
+
attestationPda: pda,
|
|
2350
|
+
bump
|
|
2351
|
+
};
|
|
2352
|
+
}
|
|
2353
|
+
/**
|
|
2354
|
+
* Derive schema PDA for a credential
|
|
2355
|
+
*
|
|
2356
|
+
* PDA seeds: ["schema", credential, schema_name]
|
|
2357
|
+
*
|
|
2358
|
+
* @param credentialAddress - Credential address
|
|
2359
|
+
* @param schemaName - Schema identifier
|
|
2360
|
+
* @returns Schema PDA and bump
|
|
2361
|
+
*/
|
|
2362
|
+
static async deriveSchemaPda(credentialAddress, schemaName) {
|
|
2363
|
+
const [pda, bump] = await getProgramDerivedAddress({
|
|
2364
|
+
programAddress: SAS_PROGRAM_ID,
|
|
2365
|
+
seeds: [
|
|
2366
|
+
getUtf8Encoder().encode(SCHEMA_SEED),
|
|
2367
|
+
getAddressEncoder().encode(credentialAddress),
|
|
2368
|
+
getUtf8Encoder().encode(schemaName)
|
|
2369
|
+
]
|
|
2370
|
+
});
|
|
2371
|
+
return {
|
|
2372
|
+
attestationPda: pda,
|
|
2373
|
+
bump
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2376
|
+
/**
|
|
2377
|
+
* Serialize Ghost ownership attestation data for on-chain storage
|
|
2378
|
+
*
|
|
2379
|
+
* Format: Borsh serialization
|
|
2380
|
+
* - x402_payment_address: 32 bytes
|
|
2381
|
+
* - network: String (length-prefixed)
|
|
2382
|
+
* - github_username: Option<String>
|
|
2383
|
+
* - twitter_handle: Option<String>
|
|
2384
|
+
* - timestamp: i64 (8 bytes)
|
|
2385
|
+
*
|
|
2386
|
+
* @param data - Attestation data to serialize
|
|
2387
|
+
* @returns Serialized buffer
|
|
2388
|
+
*/
|
|
2389
|
+
static serializeAttestationData(data) {
|
|
2390
|
+
const encoder = new TextEncoder();
|
|
2391
|
+
const networkBytes = encoder.encode(data.network);
|
|
2392
|
+
const githubBytes = data.githubUsername ? encoder.encode(data.githubUsername) : new Uint8Array();
|
|
2393
|
+
const twitterBytes = data.twitterHandle ? encoder.encode(data.twitterHandle) : new Uint8Array();
|
|
2394
|
+
const totalSize = 32 + // x402_payment_address
|
|
2395
|
+
4 + networkBytes.length + // network (length prefix + data)
|
|
2396
|
+
1 + (data.githubUsername ? 4 + githubBytes.length : 0) + // github option
|
|
2397
|
+
1 + (data.twitterHandle ? 4 + twitterBytes.length : 0) + // twitter option
|
|
2398
|
+
8;
|
|
2399
|
+
const buffer = new Uint8Array(totalSize);
|
|
2400
|
+
let offset = 0;
|
|
2401
|
+
const addressBytes = Buffer.from(data.x402PaymentAddress);
|
|
2402
|
+
buffer.set(addressBytes.slice(0, 32), offset);
|
|
2403
|
+
offset += 32;
|
|
2404
|
+
const networkLengthView = new DataView(buffer.buffer, offset, 4);
|
|
2405
|
+
networkLengthView.setUint32(0, networkBytes.length, true);
|
|
2406
|
+
offset += 4;
|
|
2407
|
+
buffer.set(networkBytes, offset);
|
|
2408
|
+
offset += networkBytes.length;
|
|
2409
|
+
if (data.githubUsername) {
|
|
2410
|
+
buffer[offset] = 1;
|
|
2411
|
+
offset += 1;
|
|
2412
|
+
const githubLengthView = new DataView(buffer.buffer, offset, 4);
|
|
2413
|
+
githubLengthView.setUint32(0, githubBytes.length, true);
|
|
2414
|
+
offset += 4;
|
|
2415
|
+
buffer.set(githubBytes, offset);
|
|
2416
|
+
offset += githubBytes.length;
|
|
2417
|
+
} else {
|
|
2418
|
+
buffer[offset] = 0;
|
|
2419
|
+
offset += 1;
|
|
2420
|
+
}
|
|
2421
|
+
if (data.twitterHandle) {
|
|
2422
|
+
buffer[offset] = 1;
|
|
2423
|
+
offset += 1;
|
|
2424
|
+
const twitterLengthView = new DataView(buffer.buffer, offset, 4);
|
|
2425
|
+
twitterLengthView.setUint32(0, twitterBytes.length, true);
|
|
2426
|
+
offset += 4;
|
|
2427
|
+
buffer.set(twitterBytes, offset);
|
|
2428
|
+
offset += twitterBytes.length;
|
|
2429
|
+
} else {
|
|
2430
|
+
buffer[offset] = 0;
|
|
2431
|
+
offset += 1;
|
|
2432
|
+
}
|
|
2433
|
+
const timestampView = new DataView(buffer.buffer, offset, 8);
|
|
2434
|
+
timestampView.setBigInt64(0, data.timestamp, true);
|
|
2435
|
+
return buffer;
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Get GhostSpeak default credential configuration
|
|
2439
|
+
*
|
|
2440
|
+
* This returns the official GhostSpeak credential issuer settings
|
|
2441
|
+
* for production use.
|
|
2442
|
+
*
|
|
2443
|
+
* @param issuer - Credential issuer address (typically the GhostSpeak program authority)
|
|
2444
|
+
* @returns Default credential configuration
|
|
2445
|
+
*/
|
|
2446
|
+
static getDefaultCredentialConfig(issuer) {
|
|
2447
|
+
return {
|
|
2448
|
+
issuer,
|
|
2449
|
+
name: "GhostSpeak AI Agent Ownership",
|
|
2450
|
+
description: "Attestation proving ownership of an AI agent registered on the GhostSpeak protocol",
|
|
2451
|
+
schemaUri: "https://ghostspeak.ai/schemas/agent-ownership-v1.json"
|
|
2452
|
+
};
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Check if an attestation is expired
|
|
2456
|
+
*
|
|
2457
|
+
* @param expiryTimestamp - Expiry timestamp (Unix seconds)
|
|
2458
|
+
* @param currentTimestamp - Current timestamp (defaults to now)
|
|
2459
|
+
* @returns True if expired
|
|
2460
|
+
*/
|
|
2461
|
+
static isAttestationExpired(expiryTimestamp, currentTimestamp) {
|
|
2462
|
+
const now = currentTimestamp ?? BigInt(Math.floor(Date.now() / 1e3));
|
|
2463
|
+
return expiryTimestamp < now;
|
|
2464
|
+
}
|
|
2465
|
+
/**
|
|
2466
|
+
* Calculate default expiry timestamp (1 year from now)
|
|
2467
|
+
*
|
|
2468
|
+
* @param fromTimestamp - Starting timestamp (defaults to now)
|
|
2469
|
+
* @returns Expiry timestamp
|
|
2470
|
+
*/
|
|
2471
|
+
static calculateDefaultExpiry(fromTimestamp) {
|
|
2472
|
+
const now = fromTimestamp ?? BigInt(Math.floor(Date.now() / 1e3));
|
|
2473
|
+
const oneYear = BigInt(365 * 24 * 60 * 60);
|
|
2474
|
+
return now + oneYear;
|
|
2475
|
+
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Create attestation instruction data
|
|
2478
|
+
*
|
|
2479
|
+
* NOTE: This is a helper for building the SAS create_attestation instruction.
|
|
2480
|
+
* The actual instruction building should be done using the SAS SDK or program IDL.
|
|
2481
|
+
*
|
|
2482
|
+
* @param config - Attestation configuration
|
|
2483
|
+
* @returns Prepared attestation data and PDA
|
|
2484
|
+
*/
|
|
2485
|
+
static async prepareAttestation(config) {
|
|
2486
|
+
const { attestationPda, bump } = await this.deriveAttestationPda(
|
|
2487
|
+
config.credentialAddress,
|
|
2488
|
+
config.schemaAddress,
|
|
2489
|
+
config.x402PaymentAddress
|
|
2490
|
+
// Use x402 address as nonce
|
|
2491
|
+
);
|
|
2492
|
+
const expiryTimestamp = config.expiryTimestamp ?? this.calculateDefaultExpiry();
|
|
2493
|
+
const attestationData = this.serializeAttestationData({
|
|
2494
|
+
x402PaymentAddress: config.x402PaymentAddress,
|
|
2495
|
+
network: config.network,
|
|
2496
|
+
githubUsername: config.githubUsername,
|
|
2497
|
+
twitterHandle: config.twitterHandle,
|
|
2498
|
+
timestamp: BigInt(Math.floor(Date.now() / 1e3))
|
|
2499
|
+
});
|
|
2500
|
+
return {
|
|
2501
|
+
attestationData,
|
|
2502
|
+
attestationPda,
|
|
2503
|
+
bump,
|
|
2504
|
+
expiryTimestamp
|
|
2505
|
+
};
|
|
2506
|
+
}
|
|
2507
|
+
};
|
|
2508
|
+
var DID_DOCUMENT_SEED = "did_document";
|
|
2509
|
+
var GhostModule = class extends BaseModule {
|
|
2510
|
+
constructor(config) {
|
|
2511
|
+
super(config);
|
|
2512
|
+
}
|
|
2513
|
+
/**
|
|
2514
|
+
* Claim ownership of a Ghost using SAS attestation
|
|
2515
|
+
*
|
|
2516
|
+
* This method performs the complete claim flow:
|
|
2517
|
+
* 1. Derives required PDAs (attestation, DID document)
|
|
2518
|
+
* 2. Builds the claim_ghost instruction
|
|
2519
|
+
* 3. Executes the transaction
|
|
2520
|
+
*
|
|
2521
|
+
* **Prerequisites:**
|
|
2522
|
+
* - The claimer must have already created a SAS attestation proving ownership
|
|
2523
|
+
* of the agent's x402_payment_address
|
|
2524
|
+
* - The agent must be in Unregistered or Registered status (not already claimed)
|
|
2525
|
+
*
|
|
2526
|
+
* **Results:**
|
|
2527
|
+
* - Agent status transitions to Claimed
|
|
2528
|
+
* - DID document is auto-created with did:sol:<network>:<address>
|
|
2529
|
+
* - Claimer becomes the owner of the agent
|
|
2530
|
+
*
|
|
2531
|
+
* @param claimer - Transaction signer (must own the SAS attestation)
|
|
2532
|
+
* @param params - Claim parameters
|
|
2533
|
+
* @returns Transaction signature
|
|
2534
|
+
*
|
|
2535
|
+
* @example
|
|
2536
|
+
* ```typescript
|
|
2537
|
+
* const signature = await client.ghosts.claim(signer, {
|
|
2538
|
+
* agentAddress: 'GhostAgent123...',
|
|
2539
|
+
* x402PaymentAddress: 'PaymentAddr456...',
|
|
2540
|
+
* sasCredential: 'SASCredential789...',
|
|
2541
|
+
* sasSchema: 'SASSchema012...',
|
|
2542
|
+
* network: 'devnet',
|
|
2543
|
+
* ipfsMetadataUri: 'ipfs://QmHash...',
|
|
2544
|
+
* githubUsername: 'myusername'
|
|
2545
|
+
* })
|
|
2546
|
+
* ```
|
|
2547
|
+
*/
|
|
2548
|
+
async claim(claimer, params) {
|
|
2549
|
+
const prepared = await this.prepareClaim(params);
|
|
2550
|
+
const instructionGetter = () => {
|
|
2551
|
+
return getClaimGhostInstruction({
|
|
2552
|
+
agentAccount: params.agentAddress,
|
|
2553
|
+
didDocument: prepared.didDocumentPda,
|
|
2554
|
+
sasAttestation: prepared.attestationPda,
|
|
2555
|
+
claimer,
|
|
2556
|
+
systemProgram: this.systemProgramId,
|
|
2557
|
+
sasCredential: params.sasCredential,
|
|
2558
|
+
sasSchema: params.sasSchema,
|
|
2559
|
+
ipfsMetadataUri: params.ipfsMetadataUri ?? null,
|
|
2560
|
+
network: params.network
|
|
2561
|
+
});
|
|
2562
|
+
};
|
|
2563
|
+
return this.execute(
|
|
2564
|
+
"claimGhost",
|
|
2565
|
+
instructionGetter,
|
|
2566
|
+
[claimer]
|
|
2567
|
+
);
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Prepare a Ghost claim by deriving all required PDAs
|
|
2571
|
+
*
|
|
2572
|
+
* This is useful for:
|
|
2573
|
+
* - Pre-flight validation (checking if PDAs are correct)
|
|
2574
|
+
* - Building custom transactions with manual PDA management
|
|
2575
|
+
* - Debugging claim issues
|
|
2576
|
+
*
|
|
2577
|
+
* @param params - Claim parameters
|
|
2578
|
+
* @returns Prepared claim data with derived PDAs
|
|
2579
|
+
*
|
|
2580
|
+
* @example
|
|
2581
|
+
* ```typescript
|
|
2582
|
+
* const prepared = await client.ghosts.prepareClaim({
|
|
2583
|
+
* agentAddress: 'GhostAgent123...',
|
|
2584
|
+
* x402PaymentAddress: 'PaymentAddr456...',
|
|
2585
|
+
* sasCredential: 'SASCredential789...',
|
|
2586
|
+
* sasSchema: 'SASSchema012...',
|
|
2587
|
+
* network: 'devnet'
|
|
2588
|
+
* })
|
|
2589
|
+
*
|
|
2590
|
+
* console.log('Attestation PDA:', prepared.attestationPda)
|
|
2591
|
+
* console.log('DID Document PDA:', prepared.didDocumentPda)
|
|
2592
|
+
* ```
|
|
2593
|
+
*/
|
|
2594
|
+
async prepareClaim(params) {
|
|
2595
|
+
const { attestationPda, bump: attestationBump } = await SASAttestationHelper.deriveAttestationPda(
|
|
2596
|
+
params.sasCredential,
|
|
2597
|
+
params.sasSchema,
|
|
2598
|
+
params.x402PaymentAddress
|
|
2599
|
+
);
|
|
2600
|
+
const [didDocumentPda, didDocumentBump] = await this.deriveDidDocumentPda(params.x402PaymentAddress);
|
|
2601
|
+
return {
|
|
2602
|
+
attestationPda,
|
|
2603
|
+
didDocumentPda,
|
|
2604
|
+
attestationBump,
|
|
2605
|
+
didDocumentBump
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2608
|
+
/**
|
|
2609
|
+
* Get Ghost agent account
|
|
2610
|
+
*
|
|
2611
|
+
* @param address - Agent account address
|
|
2612
|
+
* @returns Agent account data or null if not found
|
|
2613
|
+
*/
|
|
2614
|
+
async getGhostAgent(address2) {
|
|
2615
|
+
return super.getAccount(address2, "getAgentDecoder");
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Get all Ghost agents (agents with type 10 - external x402 agents)
|
|
2619
|
+
*
|
|
2620
|
+
* @returns Array of Ghost agents
|
|
2621
|
+
*/
|
|
2622
|
+
async getAllGhosts() {
|
|
2623
|
+
const GHOST_AGENT_TYPE = 10;
|
|
2624
|
+
return this.getGhostsByType(GHOST_AGENT_TYPE);
|
|
2625
|
+
}
|
|
2626
|
+
/**
|
|
2627
|
+
* Get Ghost agents by type
|
|
2628
|
+
*
|
|
2629
|
+
* @param agentType - Agent type filter (default: 10 for x402 ghosts)
|
|
2630
|
+
* @returns Array of matching Ghost agents
|
|
2631
|
+
*/
|
|
2632
|
+
async getGhostsByType(agentType = 10) {
|
|
2633
|
+
const typeBytes = Buffer.alloc(1);
|
|
2634
|
+
typeBytes.writeUInt8(agentType, 0);
|
|
2635
|
+
const filters = [{
|
|
2636
|
+
memcmp: {
|
|
2637
|
+
offset: BigInt(8),
|
|
2638
|
+
// Skip discriminator
|
|
2639
|
+
bytes: typeBytes.toString("base64"),
|
|
2640
|
+
encoding: "base64"
|
|
2641
|
+
}
|
|
2642
|
+
}];
|
|
2643
|
+
return this.getProgramAccounts("getAgentDecoder", filters);
|
|
2644
|
+
}
|
|
2645
|
+
/**
|
|
2646
|
+
* Get claimed Ghosts by owner
|
|
2647
|
+
*
|
|
2648
|
+
* @param owner - Owner address
|
|
2649
|
+
* @returns Array of Ghost agents owned by the address
|
|
2650
|
+
*/
|
|
2651
|
+
async getClaimedGhosts(owner) {
|
|
2652
|
+
const filters = [{
|
|
2653
|
+
memcmp: {
|
|
2654
|
+
offset: BigInt(9),
|
|
2655
|
+
// Skip discriminator + type
|
|
2656
|
+
bytes: owner,
|
|
2657
|
+
encoding: "base58"
|
|
2658
|
+
}
|
|
2659
|
+
}];
|
|
2660
|
+
return this.getProgramAccounts("getAgentDecoder", filters);
|
|
2661
|
+
}
|
|
2662
|
+
/**
|
|
2663
|
+
* Validate claim parameters
|
|
2664
|
+
*
|
|
2665
|
+
* Performs pre-flight checks to ensure claim will succeed:
|
|
2666
|
+
* - Agent exists and is in correct status
|
|
2667
|
+
* - Agent is not already claimed
|
|
2668
|
+
* - PDAs are correctly derived
|
|
2669
|
+
*
|
|
2670
|
+
* @param params - Claim parameters
|
|
2671
|
+
* @returns Validation result with error messages if any
|
|
2672
|
+
*/
|
|
2673
|
+
async validateClaim(params) {
|
|
2674
|
+
const errors = [];
|
|
2675
|
+
const warnings = [];
|
|
2676
|
+
const validNetworks = ["devnet", "testnet", "mainnet-beta", "localnet"];
|
|
2677
|
+
if (!validNetworks.includes(params.network)) {
|
|
2678
|
+
errors.push(`Invalid network: ${params.network}. Must be one of: ${validNetworks.join(", ")}`);
|
|
2679
|
+
}
|
|
2680
|
+
if (params.ipfsMetadataUri && !params.ipfsMetadataUri.startsWith("ipfs://")) {
|
|
2681
|
+
warnings.push('IPFS metadata URI should start with "ipfs://"');
|
|
2682
|
+
}
|
|
2683
|
+
const agent = await this.getGhostAgent(params.agentAddress);
|
|
2684
|
+
if (!agent) {
|
|
2685
|
+
errors.push(`Agent not found at address: ${params.agentAddress}`);
|
|
2686
|
+
} else {
|
|
2687
|
+
if (agent.owner !== null) {
|
|
2688
|
+
errors.push(`Agent is already claimed by: ${agent.owner}`);
|
|
2689
|
+
}
|
|
2690
|
+
if (agent.agentType !== 10) {
|
|
2691
|
+
warnings.push(`Agent type is ${agent.agentType}, expected 10 (external x402 agent)`);
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
return {
|
|
2695
|
+
valid: errors.length === 0,
|
|
2696
|
+
errors,
|
|
2697
|
+
warnings
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
// Helper methods
|
|
2701
|
+
/**
|
|
2702
|
+
* Derive DID document PDA
|
|
2703
|
+
*
|
|
2704
|
+
* Pattern: ['did_document', x402_payment_address]
|
|
2705
|
+
*
|
|
2706
|
+
* @param x402PaymentAddress - Agent's x402 payment address
|
|
2707
|
+
* @returns [DID document PDA, bump]
|
|
2708
|
+
*/
|
|
2709
|
+
async deriveDidDocumentPda(x402PaymentAddress) {
|
|
2710
|
+
const [pda, bump] = await getProgramDerivedAddress({
|
|
2711
|
+
programAddress: this.programId,
|
|
2712
|
+
seeds: [
|
|
2713
|
+
getUtf8Encoder().encode(DID_DOCUMENT_SEED),
|
|
2714
|
+
getAddressEncoder().encode(x402PaymentAddress)
|
|
2715
|
+
]
|
|
2716
|
+
});
|
|
2717
|
+
return [pda, bump];
|
|
2718
|
+
}
|
|
2719
|
+
get systemProgramId() {
|
|
2720
|
+
return SYSTEM_PROGRAM_ADDRESS;
|
|
2721
|
+
}
|
|
2722
|
+
};
|
|
2292
2723
|
|
|
2293
2724
|
// src/modules/governance/GovernanceModule.ts
|
|
2294
2725
|
var GovernanceModule = class extends BaseModule {
|
|
@@ -2334,8 +2765,8 @@ var GovernanceModule = class extends BaseModule {
|
|
|
2334
2765
|
/**
|
|
2335
2766
|
* Get governance proposal account
|
|
2336
2767
|
*/
|
|
2337
|
-
async getProposal(
|
|
2338
|
-
return super.getAccount(
|
|
2768
|
+
async getProposal(address2) {
|
|
2769
|
+
return super.getAccount(address2, "getGovernanceProposalDecoder");
|
|
2339
2770
|
}
|
|
2340
2771
|
/**
|
|
2341
2772
|
* Get all active proposals
|
|
@@ -2407,7 +2838,7 @@ var MultisigModule = class extends BaseModule {
|
|
|
2407
2838
|
};
|
|
2408
2839
|
|
|
2409
2840
|
// src/modules/did/did-types.ts
|
|
2410
|
-
var
|
|
2841
|
+
var DID_DOCUMENT_SEED2 = "did_document";
|
|
2411
2842
|
var VerificationMethodType = /* @__PURE__ */ ((VerificationMethodType2) => {
|
|
2412
2843
|
VerificationMethodType2["Ed25519VerificationKey2020"] = "Ed25519VerificationKey2020";
|
|
2413
2844
|
VerificationMethodType2["X25519KeyAgreementKey2020"] = "X25519KeyAgreementKey2020";
|
|
@@ -2452,14 +2883,14 @@ var DidErrorClass = class extends Error {
|
|
|
2452
2883
|
}
|
|
2453
2884
|
};
|
|
2454
2885
|
async function deriveDidDocumentPda(programId, controller) {
|
|
2455
|
-
const [
|
|
2886
|
+
const [address2, bump] = await getProgramDerivedAddress({
|
|
2456
2887
|
programAddress: programId,
|
|
2457
2888
|
seeds: [
|
|
2458
|
-
new TextEncoder().encode(
|
|
2889
|
+
new TextEncoder().encode(DID_DOCUMENT_SEED2),
|
|
2459
2890
|
getAddressEncoder().encode(controller)
|
|
2460
2891
|
]
|
|
2461
2892
|
});
|
|
2462
|
-
return [
|
|
2893
|
+
return [address2, bump];
|
|
2463
2894
|
}
|
|
2464
2895
|
function generateDidString(network, pubkey) {
|
|
2465
2896
|
const normalizedNetwork = network === "mainnet" ? "mainnet-beta" : network;
|
|
@@ -2885,259 +3316,6 @@ var CredentialModule = class {
|
|
|
2885
3316
|
return options?.pretty ? JSON.stringify(w3c, null, 2) : JSON.stringify(w3c);
|
|
2886
3317
|
}
|
|
2887
3318
|
};
|
|
2888
|
-
var DEFAULT_FACILITATOR_URL = "https://facilitator.payai.network";
|
|
2889
|
-
var DEFAULT_TIMEOUT = 3e4;
|
|
2890
|
-
var DEFAULT_RETRY = { attempts: 3, delayMs: 1e3 };
|
|
2891
|
-
function isPaymentRequired(response) {
|
|
2892
|
-
return response.status === 402;
|
|
2893
|
-
}
|
|
2894
|
-
async function extractPaymentRequirements(response) {
|
|
2895
|
-
const body = await response.text();
|
|
2896
|
-
try {
|
|
2897
|
-
const parsed = JSON.parse(body);
|
|
2898
|
-
if (parsed.accepts && Array.isArray(parsed.accepts)) {
|
|
2899
|
-
return parsed.accepts;
|
|
2900
|
-
}
|
|
2901
|
-
if (parsed.paymentRequirements && Array.isArray(parsed.paymentRequirements)) {
|
|
2902
|
-
return parsed.paymentRequirements;
|
|
2903
|
-
}
|
|
2904
|
-
if (parsed.scheme && parsed.payTo) {
|
|
2905
|
-
return [parsed];
|
|
2906
|
-
}
|
|
2907
|
-
} catch {
|
|
2908
|
-
}
|
|
2909
|
-
const paymentHeader = response.headers.get("x-payment-required");
|
|
2910
|
-
if (paymentHeader) {
|
|
2911
|
-
try {
|
|
2912
|
-
return JSON.parse(paymentHeader);
|
|
2913
|
-
} catch {
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
return [];
|
|
2917
|
-
}
|
|
2918
|
-
var PayAIClient = class extends EventEmitter {
|
|
2919
|
-
config;
|
|
2920
|
-
localRecords = [];
|
|
2921
|
-
constructor(config) {
|
|
2922
|
-
super();
|
|
2923
|
-
this.config = {
|
|
2924
|
-
facilitatorUrl: config.facilitatorUrl ?? DEFAULT_FACILITATOR_URL,
|
|
2925
|
-
rpcUrl: config.rpcUrl,
|
|
2926
|
-
wallet: config.wallet,
|
|
2927
|
-
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
2928
|
-
retry: config.retry ?? DEFAULT_RETRY
|
|
2929
|
-
};
|
|
2930
|
-
}
|
|
2931
|
-
// =====================================================
|
|
2932
|
-
// PUBLIC METHODS
|
|
2933
|
-
// =====================================================
|
|
2934
|
-
/**
|
|
2935
|
-
* Make a fetch request with automatic x402 payment handling
|
|
2936
|
-
*
|
|
2937
|
-
* @param url - The resource URL
|
|
2938
|
-
* @param init - Fetch options
|
|
2939
|
-
* @returns Response from the resource
|
|
2940
|
-
*/
|
|
2941
|
-
async fetch(url, init) {
|
|
2942
|
-
this.emit("request:started", url);
|
|
2943
|
-
const startTime = Date.now();
|
|
2944
|
-
try {
|
|
2945
|
-
let response = await this.fetchWithTimeout(url, init);
|
|
2946
|
-
if (isPaymentRequired(response)) {
|
|
2947
|
-
const requirements = await extractPaymentRequirements(response);
|
|
2948
|
-
this.emit("payment:required", requirements);
|
|
2949
|
-
if (requirements.length === 0) {
|
|
2950
|
-
throw new Error("Payment required but no payment options provided");
|
|
2951
|
-
}
|
|
2952
|
-
const requirement = this.selectPaymentOption(requirements);
|
|
2953
|
-
if (!requirement) {
|
|
2954
|
-
throw new Error("No compatible payment option found");
|
|
2955
|
-
}
|
|
2956
|
-
response = await this.makePaymentAndRetry(url, init ?? {}, requirement);
|
|
2957
|
-
}
|
|
2958
|
-
const durationMs = Date.now() - startTime;
|
|
2959
|
-
this.emit("request:completed", url, response.ok, durationMs);
|
|
2960
|
-
return response;
|
|
2961
|
-
} catch (error) {
|
|
2962
|
-
const durationMs = Date.now() - startTime;
|
|
2963
|
-
this.emit("request:completed", url, false, durationMs);
|
|
2964
|
-
if (error instanceof Error) {
|
|
2965
|
-
this.emit("payment:failed", error);
|
|
2966
|
-
}
|
|
2967
|
-
throw error;
|
|
2968
|
-
}
|
|
2969
|
-
}
|
|
2970
|
-
/**
|
|
2971
|
-
* Verify a payment through the PayAI facilitator
|
|
2972
|
-
*
|
|
2973
|
-
* @param paymentHeader - The payment header/payload
|
|
2974
|
-
* @param requirement - The payment requirement
|
|
2975
|
-
* @returns Verification result
|
|
2976
|
-
*/
|
|
2977
|
-
async verifyPayment(paymentHeader, requirement) {
|
|
2978
|
-
const response = await this.fetchWithTimeout(
|
|
2979
|
-
`${this.config.facilitatorUrl}/verify`,
|
|
2980
|
-
{
|
|
2981
|
-
method: "POST",
|
|
2982
|
-
headers: { "Content-Type": "application/json" },
|
|
2983
|
-
body: JSON.stringify({
|
|
2984
|
-
paymentHeader,
|
|
2985
|
-
paymentRequirements: requirement
|
|
2986
|
-
})
|
|
2987
|
-
}
|
|
2988
|
-
);
|
|
2989
|
-
return response.json();
|
|
2990
|
-
}
|
|
2991
|
-
/**
|
|
2992
|
-
* Settle a payment through the PayAI facilitator
|
|
2993
|
-
*
|
|
2994
|
-
* @param paymentHeader - The payment header/payload
|
|
2995
|
-
* @param requirement - The payment requirement
|
|
2996
|
-
* @returns Settlement result
|
|
2997
|
-
*/
|
|
2998
|
-
async settlePayment(paymentHeader, requirement) {
|
|
2999
|
-
const response = await this.fetchWithTimeout(
|
|
3000
|
-
`${this.config.facilitatorUrl}/settle`,
|
|
3001
|
-
{
|
|
3002
|
-
method: "POST",
|
|
3003
|
-
headers: { "Content-Type": "application/json" },
|
|
3004
|
-
body: JSON.stringify({
|
|
3005
|
-
paymentHeader,
|
|
3006
|
-
paymentRequirements: requirement
|
|
3007
|
-
})
|
|
3008
|
-
}
|
|
3009
|
-
);
|
|
3010
|
-
return response.json();
|
|
3011
|
-
}
|
|
3012
|
-
/**
|
|
3013
|
-
* List available resources from the PayAI facilitator
|
|
3014
|
-
*
|
|
3015
|
-
* @param options - Filter options
|
|
3016
|
-
* @returns List of available resources
|
|
3017
|
-
*/
|
|
3018
|
-
async listResources(options) {
|
|
3019
|
-
const params = new URLSearchParams();
|
|
3020
|
-
if (options?.network) params.set("network", options.network);
|
|
3021
|
-
if (options?.capability) params.set("capability", options.capability);
|
|
3022
|
-
if (options?.maxPrice) params.set("maxPrice", options.maxPrice.toString());
|
|
3023
|
-
const response = await this.fetchWithTimeout(
|
|
3024
|
-
`${this.config.facilitatorUrl}/list?${params.toString()}`
|
|
3025
|
-
);
|
|
3026
|
-
return response.json();
|
|
3027
|
-
}
|
|
3028
|
-
/**
|
|
3029
|
-
* Get locally tracked reputation records
|
|
3030
|
-
* (For payments made through this client instance)
|
|
3031
|
-
*/
|
|
3032
|
-
getLocalReputationRecords() {
|
|
3033
|
-
return [...this.localRecords];
|
|
3034
|
-
}
|
|
3035
|
-
/**
|
|
3036
|
-
* Clear local reputation records
|
|
3037
|
-
*/
|
|
3038
|
-
clearLocalReputationRecords() {
|
|
3039
|
-
this.localRecords.length = 0;
|
|
3040
|
-
}
|
|
3041
|
-
// =====================================================
|
|
3042
|
-
// PRIVATE METHODS
|
|
3043
|
-
// =====================================================
|
|
3044
|
-
/**
|
|
3045
|
-
* Select the best payment option from requirements
|
|
3046
|
-
*/
|
|
3047
|
-
selectPaymentOption(requirements) {
|
|
3048
|
-
const solanaOption = requirements.find((r) => r.network === "solana");
|
|
3049
|
-
if (solanaOption) return solanaOption;
|
|
3050
|
-
return requirements[0] ?? null;
|
|
3051
|
-
}
|
|
3052
|
-
/**
|
|
3053
|
-
* Make payment and retry the original request
|
|
3054
|
-
*/
|
|
3055
|
-
async makePaymentAndRetry(url, init, requirement) {
|
|
3056
|
-
this.emit("payment:started", requirement);
|
|
3057
|
-
const paymentHeader = await this.createPaymentHeader(requirement);
|
|
3058
|
-
const verification = await this.verifyPayment(paymentHeader, requirement);
|
|
3059
|
-
if (!verification.valid) {
|
|
3060
|
-
throw new Error(`Payment verification failed: ${verification.error ?? "Unknown error"}`);
|
|
3061
|
-
}
|
|
3062
|
-
const settlement = await this.settlePayment(paymentHeader, requirement);
|
|
3063
|
-
if (!settlement.success) {
|
|
3064
|
-
throw new Error(`Payment settlement failed: ${settlement.error ?? "Unknown error"}`);
|
|
3065
|
-
}
|
|
3066
|
-
this.emit("payment:completed", {
|
|
3067
|
-
success: true,
|
|
3068
|
-
transactionSignature: settlement.transaction,
|
|
3069
|
-
paymentId: `pay_${Date.now()}`
|
|
3070
|
-
});
|
|
3071
|
-
const startTime = Date.now();
|
|
3072
|
-
const response = await this.fetchWithTimeout(url, {
|
|
3073
|
-
...init,
|
|
3074
|
-
headers: {
|
|
3075
|
-
...init.headers,
|
|
3076
|
-
"X-Payment": paymentHeader,
|
|
3077
|
-
"X-Payment-Signature": settlement.transaction ?? ""
|
|
3078
|
-
}
|
|
3079
|
-
});
|
|
3080
|
-
const responseTime = Date.now() - startTime;
|
|
3081
|
-
if (settlement.transaction) {
|
|
3082
|
-
this.localRecords.push({
|
|
3083
|
-
agentAddress: requirement.payTo,
|
|
3084
|
-
paymentSignature: settlement.transaction,
|
|
3085
|
-
amount: BigInt(requirement.maxAmountRequired),
|
|
3086
|
-
success: response.ok,
|
|
3087
|
-
responseTimeMs: responseTime,
|
|
3088
|
-
payerAddress: this.config.wallet?.publicKey ?? "unknown",
|
|
3089
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
3090
|
-
network: requirement.network
|
|
3091
|
-
});
|
|
3092
|
-
}
|
|
3093
|
-
return response;
|
|
3094
|
-
}
|
|
3095
|
-
/**
|
|
3096
|
-
* Create a payment header for a requirement
|
|
3097
|
-
* (In production, this would sign a real Solana transaction)
|
|
3098
|
-
*/
|
|
3099
|
-
async createPaymentHeader(requirement) {
|
|
3100
|
-
if (!this.config.wallet) {
|
|
3101
|
-
throw new Error("Wallet not configured for payments");
|
|
3102
|
-
}
|
|
3103
|
-
const paymentData = {
|
|
3104
|
-
version: "1.0",
|
|
3105
|
-
scheme: requirement.scheme,
|
|
3106
|
-
network: requirement.network,
|
|
3107
|
-
payer: this.config.wallet.publicKey,
|
|
3108
|
-
payTo: requirement.payTo,
|
|
3109
|
-
amount: requirement.maxAmountRequired,
|
|
3110
|
-
asset: requirement.asset,
|
|
3111
|
-
resource: requirement.resource,
|
|
3112
|
-
nonce: Date.now().toString(),
|
|
3113
|
-
signature: `mock_sig_${Date.now()}`
|
|
3114
|
-
};
|
|
3115
|
-
return Buffer.from(JSON.stringify(paymentData)).toString("base64");
|
|
3116
|
-
}
|
|
3117
|
-
/**
|
|
3118
|
-
* Fetch with timeout
|
|
3119
|
-
*/
|
|
3120
|
-
async fetchWithTimeout(url, init) {
|
|
3121
|
-
const controller = new AbortController();
|
|
3122
|
-
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
3123
|
-
try {
|
|
3124
|
-
const response = await fetch(url, {
|
|
3125
|
-
...init,
|
|
3126
|
-
signal: controller.signal
|
|
3127
|
-
});
|
|
3128
|
-
return response;
|
|
3129
|
-
} finally {
|
|
3130
|
-
clearTimeout(timeoutId);
|
|
3131
|
-
}
|
|
3132
|
-
}
|
|
3133
|
-
};
|
|
3134
|
-
function createPayAIClient(config) {
|
|
3135
|
-
return new PayAIClient(config);
|
|
3136
|
-
}
|
|
3137
|
-
async function payAIFetch(url, config, init) {
|
|
3138
|
-
const client = createPayAIClient(config);
|
|
3139
|
-
return client.fetch(url, init);
|
|
3140
|
-
}
|
|
3141
3319
|
|
|
3142
3320
|
// src/modules/reputation/ReputationModule.ts
|
|
3143
3321
|
init_reputation_tag_engine();
|
|
@@ -3677,6 +3855,6 @@ var StakingModule = class extends BaseModule {
|
|
|
3677
3855
|
}
|
|
3678
3856
|
};
|
|
3679
3857
|
|
|
3680
|
-
export { AgentModule, BaseModule, CacheManager, CredentialKind, CredentialModule, CredentialStatus, DEFAULT_IPFS_CONFIG, DidError, DidErrorClass, GovernanceModule, IPFSUtils, InstructionBuilder, MultiSourceAggregator, MultiSourceAggregator_exports, MultisigModule,
|
|
3681
|
-
//# sourceMappingURL=chunk-
|
|
3682
|
-
//# sourceMappingURL=chunk-
|
|
3858
|
+
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 };
|
|
3859
|
+
//# sourceMappingURL=chunk-63A7F2YP.js.map
|
|
3860
|
+
//# sourceMappingURL=chunk-63A7F2YP.js.map
|