@ghostspeak/sdk 2.0.7 → 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.
- package/README.md +145 -2
- package/dist/{GhostSpeakClient-CWmGaM9Q.d.ts → GhostSpeakClient-bnXwUPHI.d.ts} +10 -6
- package/dist/{StakingModule-C5rzuOWb.d.ts → StakingModule-DunDShLq.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-CI5_6Gzk.d.ts +234 -0
- package/dist/browser.d.ts +3 -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-G7S6B6WB.js → chunk-5QBSC4T4.js} +7 -7
- package/dist/{chunk-G7S6B6WB.js.map → chunk-5QBSC4T4.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-6XCCMJ6M.js} +19 -23
- package/dist/chunk-6XCCMJ6M.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-S74EH3KD.js → chunk-IQM5RASO.js} +637 -25
- package/dist/chunk-IQM5RASO.js.map +1 -0
- package/dist/{chunk-SZGFSCNU.js → chunk-JYXSOXCP.js} +467 -299
- package/dist/chunk-JYXSOXCP.js.map +1 -0
- package/dist/{chunk-C5CDA3WX.js → chunk-OXA7MECJ.js} +476 -3
- package/dist/chunk-OXA7MECJ.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/client.d.ts +2 -3
- package/dist/client.js +9 -9
- 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 +209 -231
- package/dist/index.js +231 -521
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/minimal/core-minimal.d.ts +266 -184
- 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/{updateReputationWithAuth-Y4ONEVSP.js → updateReputationWithAuth-PCEUOCFV.js} +4 -4
- package/dist/{updateReputationWithAuth-Y4ONEVSP.js.map → updateReputationWithAuth-PCEUOCFV.js.map} +1 -1
- package/dist/utils.js +9 -9
- package/package.json +4 -4
- package/dist/chunk-AL3HQN73.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, 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
3
|
import { __export, __esm } from './chunk-UP2VWCW5.js';
|
|
4
|
-
import { createSolanaRpc, createSolanaRpcSubscriptions, lamports, pipe, createTransactionMessage, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, signTransactionMessageWithSigners, setTransactionMessageFeePayer, compileTransactionMessage, getBase64EncodedWireTransaction, getProgramDerivedAddress, getAddressEncoder } from '@solana/kit';
|
|
4
|
+
import { createSolanaRpc, createSolanaRpcSubscriptions, 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 = {};
|
|
@@ -282,9 +282,9 @@ var RpcClient = class {
|
|
|
282
282
|
/**
|
|
283
283
|
* Get account information with automatic retries
|
|
284
284
|
*/
|
|
285
|
-
async getAccountInfo(
|
|
285
|
+
async getAccountInfo(address2, options) {
|
|
286
286
|
return this.withRetry(async () => {
|
|
287
|
-
const result = await this.rpc.getAccountInfo(
|
|
287
|
+
const result = await this.rpc.getAccountInfo(address2, {
|
|
288
288
|
commitment: options?.commitment ?? this.commitment,
|
|
289
289
|
encoding: "base64"
|
|
290
290
|
}).send();
|
|
@@ -429,14 +429,14 @@ var RpcClient = class {
|
|
|
429
429
|
* Subscribe to account changes (WebSocket)
|
|
430
430
|
* Note: This is a placeholder implementation. In production, you would use the actual subscription API
|
|
431
431
|
*/
|
|
432
|
-
async subscribeToAccount(
|
|
432
|
+
async subscribeToAccount(address2, callback) {
|
|
433
433
|
if (!this.rpcSubscriptions) {
|
|
434
434
|
throw new Error("WebSocket endpoint not configured");
|
|
435
435
|
}
|
|
436
436
|
console.warn("Account subscription is not fully implemented in this version");
|
|
437
437
|
const intervalId = setInterval(async () => {
|
|
438
438
|
try {
|
|
439
|
-
const accountInfo = await this.getAccountInfo(
|
|
439
|
+
const accountInfo = await this.getAccountInfo(address2);
|
|
440
440
|
callback(accountInfo);
|
|
441
441
|
} catch (error) {
|
|
442
442
|
console.error("Subscription polling error:", error);
|
|
@@ -946,19 +946,19 @@ var InstructionBuilder = class {
|
|
|
946
946
|
/**
|
|
947
947
|
* Get and decode account data with unified error handling
|
|
948
948
|
*/
|
|
949
|
-
async getAccount(
|
|
949
|
+
async getAccount(address2, decoderImportName) {
|
|
950
950
|
try {
|
|
951
|
-
const accountInfo = await this.rpcClient.getAccountInfo(
|
|
951
|
+
const accountInfo = await this.rpcClient.getAccountInfo(address2, {
|
|
952
952
|
commitment: this.config.commitment
|
|
953
953
|
});
|
|
954
954
|
if (!accountInfo) return null;
|
|
955
|
-
const generated = await import('./generated-
|
|
955
|
+
const generated = await import('./generated-QJREJQ2C.js');
|
|
956
956
|
const decoderGetter = generated[decoderImportName];
|
|
957
957
|
const decoder = decoderGetter();
|
|
958
958
|
const rawData = this.extractRawData(accountInfo.data);
|
|
959
959
|
return decoder.decode(rawData);
|
|
960
960
|
} catch (error) {
|
|
961
|
-
console.warn(`Failed to fetch account ${
|
|
961
|
+
console.warn(`Failed to fetch account ${address2}:`, error);
|
|
962
962
|
return null;
|
|
963
963
|
}
|
|
964
964
|
}
|
|
@@ -970,7 +970,7 @@ var InstructionBuilder = class {
|
|
|
970
970
|
const accounts = await this.rpcClient.getMultipleAccounts(addresses, {
|
|
971
971
|
commitment: this.config.commitment
|
|
972
972
|
});
|
|
973
|
-
const generated = await import('./generated-
|
|
973
|
+
const generated = await import('./generated-QJREJQ2C.js');
|
|
974
974
|
const decoderGetter = generated[decoderImportName];
|
|
975
975
|
const decoder = decoderGetter();
|
|
976
976
|
return accounts.map((accountInfo) => {
|
|
@@ -1020,7 +1020,7 @@ var InstructionBuilder = class {
|
|
|
1020
1020
|
commitment: this.config.commitment,
|
|
1021
1021
|
filters: convertedFilters ?? []
|
|
1022
1022
|
});
|
|
1023
|
-
const generated = await import('./generated-
|
|
1023
|
+
const generated = await import('./generated-QJREJQ2C.js');
|
|
1024
1024
|
const decoderGetter = generated[decoderImportName];
|
|
1025
1025
|
const decoder = decoderGetter();
|
|
1026
1026
|
const decodedAccounts = [];
|
|
@@ -1348,9 +1348,9 @@ var CacheManager = class {
|
|
|
1348
1348
|
* @param currentSlot - Current blockchain slot (for staleness check)
|
|
1349
1349
|
* @returns Cached data or undefined
|
|
1350
1350
|
*/
|
|
1351
|
-
getAccount(
|
|
1351
|
+
getAccount(address2, commitment, currentSlot) {
|
|
1352
1352
|
if (!this.config.enabled) return void 0;
|
|
1353
|
-
const key = `${
|
|
1353
|
+
const key = `${address2}:${commitment}`;
|
|
1354
1354
|
const entry = this.accountCache.get(key);
|
|
1355
1355
|
if (!entry) return void 0;
|
|
1356
1356
|
if (currentSlot !== void 0 && entry.slot < currentSlot) {
|
|
@@ -1367,9 +1367,9 @@ var CacheManager = class {
|
|
|
1367
1367
|
* @param commitment - Commitment level
|
|
1368
1368
|
* @param slot - Blockchain slot when data was fetched
|
|
1369
1369
|
*/
|
|
1370
|
-
setAccount(
|
|
1370
|
+
setAccount(address2, data, commitment, slot) {
|
|
1371
1371
|
if (!this.config.enabled) return;
|
|
1372
|
-
const key = `${
|
|
1372
|
+
const key = `${address2}:${commitment}`;
|
|
1373
1373
|
const entry = {
|
|
1374
1374
|
data,
|
|
1375
1375
|
slot,
|
|
@@ -1408,13 +1408,13 @@ var CacheManager = class {
|
|
|
1408
1408
|
* @param address - Account address to invalidate
|
|
1409
1409
|
* @param commitment - Optional commitment level (invalidates all if not specified)
|
|
1410
1410
|
*/
|
|
1411
|
-
invalidateAccount(
|
|
1411
|
+
invalidateAccount(address2, commitment) {
|
|
1412
1412
|
if (!this.config.enabled) return;
|
|
1413
1413
|
if (commitment) {
|
|
1414
|
-
this.accountCache.delete(`${
|
|
1414
|
+
this.accountCache.delete(`${address2}:${commitment}`);
|
|
1415
1415
|
} else {
|
|
1416
1416
|
["processed", "confirmed", "finalized"].forEach((c) => {
|
|
1417
|
-
this.accountCache.delete(`${
|
|
1417
|
+
this.accountCache.delete(`${address2}:${c}`);
|
|
1418
1418
|
});
|
|
1419
1419
|
}
|
|
1420
1420
|
}
|
|
@@ -1540,19 +1540,19 @@ var BaseModule = class {
|
|
|
1540
1540
|
/**
|
|
1541
1541
|
* Get decoded account (with optional caching)
|
|
1542
1542
|
*/
|
|
1543
|
-
async getAccount(
|
|
1543
|
+
async getAccount(address2, decoderImportName) {
|
|
1544
1544
|
if (this.cacheManager.isEnabled()) {
|
|
1545
|
-
const cached = this.cacheManager.getAccount(
|
|
1545
|
+
const cached = this.cacheManager.getAccount(address2, this.commitment);
|
|
1546
1546
|
if (cached !== void 0) {
|
|
1547
|
-
this.logger?.info(`[Cache HIT] ${
|
|
1547
|
+
this.logger?.info(`[Cache HIT] ${address2}`);
|
|
1548
1548
|
return cached;
|
|
1549
1549
|
}
|
|
1550
1550
|
}
|
|
1551
|
-
const account = await this.builder.getAccount(
|
|
1551
|
+
const account = await this.builder.getAccount(address2, decoderImportName);
|
|
1552
1552
|
if (this.cacheManager.isEnabled() && account !== null) {
|
|
1553
1553
|
const slot = 0;
|
|
1554
|
-
this.cacheManager.setAccount(
|
|
1555
|
-
this.logger?.info(`[Cache SET] ${
|
|
1554
|
+
this.cacheManager.setAccount(address2, account, this.commitment, slot);
|
|
1555
|
+
this.logger?.info(`[Cache SET] ${address2}`);
|
|
1556
1556
|
}
|
|
1557
1557
|
return account;
|
|
1558
1558
|
}
|
|
@@ -1624,9 +1624,9 @@ var BaseModule = class {
|
|
|
1624
1624
|
/**
|
|
1625
1625
|
* Invalidate cache for specific account
|
|
1626
1626
|
*/
|
|
1627
|
-
invalidateCache(
|
|
1628
|
-
this.cacheManager.invalidateAccount(
|
|
1629
|
-
this.logger?.info(`[Cache INVALIDATE] ${
|
|
1627
|
+
invalidateCache(address2) {
|
|
1628
|
+
this.cacheManager.invalidateAccount(address2);
|
|
1629
|
+
this.logger?.info(`[Cache INVALIDATE] ${address2}`);
|
|
1630
1630
|
}
|
|
1631
1631
|
/**
|
|
1632
1632
|
* Clear all caches
|
|
@@ -2147,8 +2147,8 @@ var AgentModule = class extends BaseModule {
|
|
|
2147
2147
|
/**
|
|
2148
2148
|
* Get agent account
|
|
2149
2149
|
*/
|
|
2150
|
-
async getAgentAccount(
|
|
2151
|
-
return super.getAccount(
|
|
2150
|
+
async getAgentAccount(address2) {
|
|
2151
|
+
return super.getAccount(address2, "getAgentDecoder");
|
|
2152
2152
|
}
|
|
2153
2153
|
/**
|
|
2154
2154
|
* Get all agents
|
|
@@ -2262,18 +2262,18 @@ var AgentModule = class extends BaseModule {
|
|
|
2262
2262
|
// Helper methods
|
|
2263
2263
|
async deriveAgentPda(agentId, owner) {
|
|
2264
2264
|
const { deriveAgentPda } = await import('./pda-4KP7CURF.js');
|
|
2265
|
-
const [
|
|
2266
|
-
return
|
|
2265
|
+
const [address2] = await deriveAgentPda({ programAddress: this.programId, owner, agentId });
|
|
2266
|
+
return address2;
|
|
2267
2267
|
}
|
|
2268
2268
|
async deriveUserRegistryPda(owner) {
|
|
2269
2269
|
const { deriveUserRegistryPda } = await import('./pda-4KP7CURF.js');
|
|
2270
2270
|
return deriveUserRegistryPda(this.programId, owner);
|
|
2271
2271
|
}
|
|
2272
2272
|
async deriveTreeConfigPda(owner) {
|
|
2273
|
-
const { getProgramDerivedAddress:
|
|
2274
|
-
const addressEncoder =
|
|
2273
|
+
const { getProgramDerivedAddress: getProgramDerivedAddress4, getAddressEncoder: getAddressEncoder4 } = await import('@solana/addresses');
|
|
2274
|
+
const addressEncoder = getAddressEncoder4();
|
|
2275
2275
|
const ownerBytes = addressEncoder.encode(owner);
|
|
2276
|
-
const [pda] = await
|
|
2276
|
+
const [pda] = await getProgramDerivedAddress4({
|
|
2277
2277
|
programAddress: this.programId,
|
|
2278
2278
|
seeds: [
|
|
2279
2279
|
new TextEncoder().encode("agent_tree_config"),
|
|
@@ -2289,6 +2289,427 @@ var AgentModule = class extends BaseModule {
|
|
|
2289
2289
|
return "cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK";
|
|
2290
2290
|
}
|
|
2291
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
|
+
};
|
|
2292
2713
|
|
|
2293
2714
|
// src/modules/governance/GovernanceModule.ts
|
|
2294
2715
|
var GovernanceModule = class extends BaseModule {
|
|
@@ -2334,8 +2755,8 @@ var GovernanceModule = class extends BaseModule {
|
|
|
2334
2755
|
/**
|
|
2335
2756
|
* Get governance proposal account
|
|
2336
2757
|
*/
|
|
2337
|
-
async getProposal(
|
|
2338
|
-
return super.getAccount(
|
|
2758
|
+
async getProposal(address2) {
|
|
2759
|
+
return super.getAccount(address2, "getGovernanceProposalDecoder");
|
|
2339
2760
|
}
|
|
2340
2761
|
/**
|
|
2341
2762
|
* Get all active proposals
|
|
@@ -2407,7 +2828,7 @@ var MultisigModule = class extends BaseModule {
|
|
|
2407
2828
|
};
|
|
2408
2829
|
|
|
2409
2830
|
// src/modules/did/did-types.ts
|
|
2410
|
-
var
|
|
2831
|
+
var DID_DOCUMENT_SEED2 = "did_document";
|
|
2411
2832
|
var VerificationMethodType = /* @__PURE__ */ ((VerificationMethodType2) => {
|
|
2412
2833
|
VerificationMethodType2["Ed25519VerificationKey2020"] = "Ed25519VerificationKey2020";
|
|
2413
2834
|
VerificationMethodType2["X25519KeyAgreementKey2020"] = "X25519KeyAgreementKey2020";
|
|
@@ -2452,14 +2873,14 @@ var DidErrorClass = class extends Error {
|
|
|
2452
2873
|
}
|
|
2453
2874
|
};
|
|
2454
2875
|
async function deriveDidDocumentPda(programId, controller) {
|
|
2455
|
-
const [
|
|
2876
|
+
const [address2, bump] = await getProgramDerivedAddress({
|
|
2456
2877
|
programAddress: programId,
|
|
2457
2878
|
seeds: [
|
|
2458
|
-
new TextEncoder().encode(
|
|
2879
|
+
new TextEncoder().encode(DID_DOCUMENT_SEED2),
|
|
2459
2880
|
getAddressEncoder().encode(controller)
|
|
2460
2881
|
]
|
|
2461
2882
|
});
|
|
2462
|
-
return [
|
|
2883
|
+
return [address2, bump];
|
|
2463
2884
|
}
|
|
2464
2885
|
function generateDidString(network, pubkey) {
|
|
2465
2886
|
const normalizedNetwork = network === "mainnet" ? "mainnet-beta" : network;
|
|
@@ -2885,259 +3306,6 @@ var CredentialModule = class {
|
|
|
2885
3306
|
return options?.pretty ? JSON.stringify(w3c, null, 2) : JSON.stringify(w3c);
|
|
2886
3307
|
}
|
|
2887
3308
|
};
|
|
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
3309
|
|
|
3142
3310
|
// src/modules/reputation/ReputationModule.ts
|
|
3143
3311
|
init_reputation_tag_engine();
|
|
@@ -3677,6 +3845,6 @@ var StakingModule = class extends BaseModule {
|
|
|
3677
3845
|
}
|
|
3678
3846
|
};
|
|
3679
3847
|
|
|
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-
|
|
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
|