@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
package/dist/index.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
export { batchGetAccounts, batchGetAccountsWithRetry, batchGetAndMap, batchGetExistingAccounts, createBatchFetcher } from './chunk-SKMJJ3Q6.js';
|
|
2
2
|
export { BaseReputationAdapter, GHOSTSPEAK_PROGRAM_ID, ReputationSource } from './chunk-TTB4OS2D.js';
|
|
3
|
-
export { AuthorizationModule, DidModule, GhostSpeakClient, PrivacyModule, UnifiedCredentialService, calculateVisibleScore, canViewerAccess, GhostSpeakClient_default as default, filterMetricsByVisibility, getDefaultMetricVisibility, getRangeDisplayString, getReputationTier, getScoreRange, getTierDisplayName, lamportsToSol, sol, validatePrivacySettings } from './chunk-
|
|
4
|
-
import { init_MultiSourceAggregator } from './chunk-
|
|
5
|
-
export { AgentModule, BaseModule, CacheManager, CredentialKind, CredentialModule, CredentialStatus, DEFAULT_IPFS_CONFIG, DidError, DidErrorClass, GovernanceModule, IPFSUtils, InstructionBuilder, MultiSourceAggregator, MultisigModule,
|
|
3
|
+
export { AuthorizationModule, DidModule, GhostSpeakClient, PrivacyModule, UnifiedCredentialService, calculateVisibleScore, canViewerAccess, GhostSpeakClient_default as default, filterMetricsByVisibility, getDefaultMetricVisibility, getRangeDisplayString, getReputationTier, getScoreRange, getTierDisplayName, lamportsToSol, sol, validatePrivacySettings } from './chunk-5SS3OL4B.js';
|
|
4
|
+
import { init_MultiSourceAggregator, BaseModule } from './chunk-63A7F2YP.js';
|
|
5
|
+
export { ATTESTATION_SEED, AgentModule, BaseModule, CREDENTIAL_SEED, CacheManager, CredentialKind, CredentialModule, CredentialStatus, DEFAULT_IPFS_CONFIG, DidError, DidErrorClass, GhostModule, GovernanceModule, IPFSUtils, InstructionBuilder, MultiSourceAggregator, 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, isDidActive, parseDidString, validateDidString } from './chunk-63A7F2YP.js';
|
|
6
6
|
export { AccountNotFoundError, ErrorFactory, ErrorHandler, GhostSpeakError, InsufficientBalanceError, InvalidInputError, NetworkError, SimulationFailedError, TimeoutError, TransactionFailedError, ValidationError } from './chunk-5DMB3UAV.js';
|
|
7
7
|
export { decrypt, elgamal_exports as elgamal, encrypt, generateKeypair, generateTransferProof, generateWithdrawProof, isWasmAvailable, loadWasmModule, wasm_bridge_exports as wasmBridge } from './chunk-VQZQCHUT.js';
|
|
8
|
-
import { getFeatureFlags, ClientEncryptionService } from './chunk-
|
|
9
|
-
export { ClientEncryptionService, FeatureFlagManager, TokenExtension, TokenProgram, createDiscriminatorErrorMessage, createMigrationPlan, createMigrationReport, deriveAssociatedTokenAddress, deriveMultisigPda, deriveProposalPda, deriveSplTokenAssociatedTokenAddress, deriveToken2022AssociatedTokenAddress, detectTokenProgram, diagnoseAccountFromChain, diagnoseBatchFromChain, exportDiagnosticReport, extractLegacyData, formatTokenAmount, generateLocalPrivacyProof, getAllAssociatedTokenAddresses, getAssociatedTokenAccount, getConfidentialTransferConfig, getFeatureFlags, getInterestBearingConfig, getMigrationInstructions, getTokenProgramAddress, getTokenProgramFromAddress, getTokenProgramType, getTransferFeeConfig, hasConfidentialTransferExtension, hasInterestBearingExtension, hasTransferFeeExtension, inspectAccountData, isFeatureEnabled, isToken2022Mint, parseTokenAmount, runAccountDiagnostics, runBatchDiagnostics, safeDecodeAgent, simulateMigration, validateAccountDiscriminator, validateAssociatedTokenAddress, verifyLocalPrivacyProof } from './chunk-
|
|
8
|
+
import { getFeatureFlags, ClientEncryptionService } from './chunk-EU6PHSM5.js';
|
|
9
|
+
export { ClientEncryptionService, FeatureFlagManager, TokenExtension, TokenProgram, createDiscriminatorErrorMessage, createMigrationPlan, createMigrationReport, deriveAssociatedTokenAddress, deriveMultisigPda, deriveProposalPda, deriveSplTokenAssociatedTokenAddress, deriveToken2022AssociatedTokenAddress, detectTokenProgram, diagnoseAccountFromChain, diagnoseBatchFromChain, exportDiagnosticReport, extractLegacyData, formatTokenAmount, generateLocalPrivacyProof, getAllAssociatedTokenAddresses, getAssociatedTokenAccount, getConfidentialTransferConfig, getFeatureFlags, getInterestBearingConfig, getMigrationInstructions, getTokenProgramAddress, getTokenProgramFromAddress, getTokenProgramType, getTransferFeeConfig, hasConfidentialTransferExtension, hasInterestBearingExtension, hasTransferFeeExtension, inspectAccountData, isFeatureEnabled, isToken2022Mint, parseTokenAmount, runAccountDiagnostics, runBatchDiagnostics, safeDecodeAgent, simulateMigration, validateAccountDiscriminator, validateAssociatedTokenAddress, verifyLocalPrivacyProof } from './chunk-EU6PHSM5.js';
|
|
10
10
|
export { deriveAgentPda, deriveAgentVerificationPda, deriveUserRegistryPda, findProgramDerivedAddress } from './chunk-BF3IQ35I.js';
|
|
11
|
-
export { createAuthorizationMessage, createSignedAuthorization, deserializeAuthorization, generateNonce, getAuthorizationId, isAuthorizationExhausted, isAuthorizationExpired, serializeAuthorization, signAuthorizationMessage, validateAuthorizationNetwork, verifyAuthorizationSignature } from './chunk-
|
|
12
|
-
import { init_reputation_tag_engine, init_reputation_tags } from './chunk-
|
|
13
|
-
export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, BadgeType, BehaviorTag, ComplianceTag, DEFAULT_TAG_DECAY, GhostSpeakSDKError, INSTRUCTION_MAPPINGS, IPFSClient, InstructionValidationError, NATIVE_MINT_ADDRESS, PRIVACY_CONSTANTS, PrivacyMode, PrivacyPresets, REPUTATION_CONSTANTS, ReputationTagEngine, ReputationTier, ScoreRange, SkillTag, TAG_CONSTANTS, TOKEN_2022_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS, TagCategory, TagConfidenceLevel, VisibilityLevel, createAccountMismatchError, createErrorContext, debugInstructionCall, enhanceErrorMessage, enhanceTransactionError, extractInstructionName, generateAccountValidationError, getAccountRequirements, getInstructionMapping, getPDAAccounts, getRequiredSigners, getWritableAccounts, isKnownInstruction, logEnhancedError, validateInstructionAccounts, validatePreconditions, withEnhancedErrors, withEnhancedErrorsSync } from './chunk-
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
|
|
17
|
-
import './chunk-
|
|
18
|
-
import './chunk-
|
|
19
|
-
|
|
11
|
+
export { createAuthorizationMessage, createSignedAuthorization, deserializeAuthorization, generateNonce, getAuthorizationId, isAuthorizationExhausted, isAuthorizationExpired, serializeAuthorization, signAuthorizationMessage, validateAuthorizationNetwork, verifyAuthorizationSignature } from './chunk-QWQTPTZ4.js';
|
|
12
|
+
import { init_reputation_tag_engine, init_reputation_tags, ExternalIdNotFoundError, GhostSpeakError, GhostNotFoundError } from './chunk-HIDBANFS.js';
|
|
13
|
+
export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, BadgeType, BehaviorTag, ComplianceTag, DEFAULT_TAG_DECAY, GhostSpeakSDKError, INSTRUCTION_MAPPINGS, IPFSClient, InstructionValidationError, NATIVE_MINT_ADDRESS, PRIVACY_CONSTANTS, PrivacyMode, PrivacyPresets, REPUTATION_CONSTANTS, ReputationTagEngine, ReputationTier, ScoreRange, SkillTag, TAG_CONSTANTS, TOKEN_2022_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS, TagCategory, TagConfidenceLevel, VisibilityLevel, createAccountMismatchError, createErrorContext, debugInstructionCall, enhanceErrorMessage, enhanceTransactionError, extractInstructionName, generateAccountValidationError, getAccountRequirements, getInstructionMapping, getPDAAccounts, getRequiredSigners, getWritableAccounts, isKnownInstruction, logEnhancedError, validateInstructionAccounts, validatePreconditions, withEnhancedErrors, withEnhancedErrorsSync } from './chunk-HIDBANFS.js';
|
|
14
|
+
import { getCreateEscrowInstructionAsync, getSubmitDeliveryInstruction, getApproveDeliveryInstruction, getFileDisputeInstruction, getArbitrateDisputeInstruction } from './chunk-IQM5RASO.js';
|
|
15
|
+
export { getApproveDeliveryInstruction, getArbitrateDisputeInstruction, getClaimGhostInstruction, getCreateDidDocumentInstructionAsync, getCreateEscrowInstructionAsync, getDeactivateDidDocumentInstructionAsync, getFileDisputeInstruction, getGhostProtectEscrowDecoder, getInitializeStakingConfigInstructionAsync, getRegisterAgentInstructionAsync, getResolveDidDocumentInstructionAsync, getSlashStakeInstructionAsync, getStakeGhostInstructionAsync, getStakingAccountDecoder, getStakingConfigDecoder, getSubmitDeliveryInstruction, getUnstakeGhostInstructionAsync, getUpdateDidDocumentInstructionAsync, getUpdateReputationTagsInstructionAsync } from './chunk-IQM5RASO.js';
|
|
16
|
+
export { ProposalStatus, decodeAgent, fetchAgent, fetchMaybeAgent, getAgentDecoder } from './chunk-5QZVFUXB.js';
|
|
17
|
+
import './chunk-46QWY3MG.js';
|
|
18
|
+
import './chunk-A7ALCVUI.js';
|
|
19
|
+
import './chunk-QLRWUHN2.js';
|
|
20
|
+
export { GHOSTSPEAK_MARKETPLACE_PROGRAM_ADDRESS } from './chunk-AWMGX3OX.js';
|
|
20
21
|
export { AgentType, ChannelType, ErrorCode, EscrowStatus, MessageType, ParticipantType, isError, isSuccess, unwrap } from './chunk-SRS2SKFS.js';
|
|
21
22
|
export { CrossmintVCClient, GHOSTSPEAK_CREDENTIAL_TYPES } from './chunk-RIZZPLLB.js';
|
|
22
23
|
import { __require } from './chunk-UP2VWCW5.js';
|
|
23
24
|
import { createSolanaRpc, lamports, pipe, createTransactionMessage, setTransactionMessageFeePayer, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstructions, signTransactionMessageWithSigners, getBase64EncodedWireTransaction, createKeyPairSignerFromBytes, generateKeyPairSigner } from '@solana/kit';
|
|
24
25
|
export { address, createKeyPairSignerFromBytes, createSolanaRpc, generateKeyPairSigner } from '@solana/kit';
|
|
25
|
-
import {
|
|
26
|
-
import { timingSafeEqual, createHmac } from 'crypto';
|
|
26
|
+
import { address } from '@solana/addresses';
|
|
27
27
|
import { getTransferSolInstruction } from '@solana-program/system';
|
|
28
28
|
import { promises } from 'fs';
|
|
29
29
|
import process2 from 'process';
|
|
@@ -32,8 +32,323 @@ import tty from 'tty';
|
|
|
32
32
|
import bs58 from 'bs58';
|
|
33
33
|
import { sha256 } from '@noble/hashes/sha256';
|
|
34
34
|
import { bytesToHex, hexToBytes } from '@noble/curves/abstract/utils';
|
|
35
|
-
import { address } from '@solana/addresses';
|
|
36
35
|
|
|
36
|
+
var DEFAULT_API_URL = "https://api.ghostspeak.ai";
|
|
37
|
+
var DEVNET_API_URL = "https://api-devnet.ghostspeak.ai";
|
|
38
|
+
var LOCALNET_API_URL = "http://localhost:3001";
|
|
39
|
+
var ExternalIdResolver = class {
|
|
40
|
+
apiUrl;
|
|
41
|
+
constructor(config) {
|
|
42
|
+
if (config?.apiUrl) {
|
|
43
|
+
this.apiUrl = config.apiUrl;
|
|
44
|
+
} else {
|
|
45
|
+
const cluster = config?.cluster || "devnet";
|
|
46
|
+
this.apiUrl = cluster === "mainnet-beta" ? DEFAULT_API_URL : cluster === "localnet" ? LOCALNET_API_URL : DEVNET_API_URL;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve external ID to Ghost address
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* const address = await resolver.resolve('payai', 'agent-123');
|
|
54
|
+
*/
|
|
55
|
+
async resolve(platform, externalId) {
|
|
56
|
+
const result = await this.lookup(platform, externalId);
|
|
57
|
+
return address(result.mapping.ghostAddress);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Lookup external ID with full Ghost data
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const { mapping, ghost } = await resolver.lookup('payai', 'agent-123');
|
|
64
|
+
*/
|
|
65
|
+
async lookup(platform, externalId) {
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(
|
|
68
|
+
`${this.apiUrl}/ghosts/external/${encodeURIComponent(platform)}/${encodeURIComponent(externalId)}`
|
|
69
|
+
);
|
|
70
|
+
if (response.status === 404) {
|
|
71
|
+
throw new ExternalIdNotFoundError(platform, externalId);
|
|
72
|
+
}
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const error = await response.json().catch(() => ({}));
|
|
75
|
+
throw new GhostSpeakError(
|
|
76
|
+
error.message || "Failed to lookup external ID",
|
|
77
|
+
error.code || "LOOKUP_FAILED"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
return data;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (error instanceof GhostSpeakError || error instanceof ExternalIdNotFoundError) throw error;
|
|
84
|
+
throw new GhostSpeakError(
|
|
85
|
+
"Failed to lookup external ID",
|
|
86
|
+
"LOOKUP_FAILED"
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get Ghost by Solana address via API
|
|
92
|
+
*
|
|
93
|
+
* Faster than on-chain lookup for read operations
|
|
94
|
+
*/
|
|
95
|
+
async getGhost(ghostAddress) {
|
|
96
|
+
try {
|
|
97
|
+
const addrString = typeof ghostAddress === "string" ? ghostAddress : ghostAddress;
|
|
98
|
+
const response = await fetch(
|
|
99
|
+
`${this.apiUrl}/ghosts/${encodeURIComponent(addrString)}`
|
|
100
|
+
);
|
|
101
|
+
if (response.status === 404) {
|
|
102
|
+
throw new GhostNotFoundError(addrString);
|
|
103
|
+
}
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const error = await response.json().catch(() => ({}));
|
|
106
|
+
throw new GhostSpeakError(
|
|
107
|
+
error.message || "Failed to fetch Ghost",
|
|
108
|
+
error.code || "FETCH_FAILED"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const ghost = await response.json();
|
|
112
|
+
return ghost;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error instanceof GhostSpeakError || error instanceof GhostNotFoundError) throw error;
|
|
115
|
+
throw new GhostSpeakError(
|
|
116
|
+
"Failed to fetch Ghost",
|
|
117
|
+
"FETCH_FAILED"
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get Ghost Score via API
|
|
123
|
+
*/
|
|
124
|
+
async getGhostScore(ghostAddress) {
|
|
125
|
+
try {
|
|
126
|
+
const addrString = typeof ghostAddress === "string" ? ghostAddress : ghostAddress;
|
|
127
|
+
const response = await fetch(
|
|
128
|
+
`${this.apiUrl}/ghosts/${encodeURIComponent(addrString)}/score`
|
|
129
|
+
);
|
|
130
|
+
if (response.status === 404) {
|
|
131
|
+
throw new GhostNotFoundError(addrString);
|
|
132
|
+
}
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
const error = await response.json().catch(() => ({}));
|
|
135
|
+
throw new GhostSpeakError(
|
|
136
|
+
error.message || "Failed to fetch Ghost Score",
|
|
137
|
+
error.code || "FETCH_FAILED"
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
const score = await response.json();
|
|
141
|
+
return score;
|
|
142
|
+
} catch (error) {
|
|
143
|
+
if (error instanceof GhostSpeakError || error instanceof GhostNotFoundError) throw error;
|
|
144
|
+
throw new GhostSpeakError(
|
|
145
|
+
"Failed to fetch Ghost Score",
|
|
146
|
+
"FETCH_FAILED"
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get detailed reputation breakdown via API
|
|
152
|
+
*/
|
|
153
|
+
async getGhostReputation(ghostAddress) {
|
|
154
|
+
try {
|
|
155
|
+
const addrString = typeof ghostAddress === "string" ? ghostAddress : ghostAddress;
|
|
156
|
+
const response = await fetch(
|
|
157
|
+
`${this.apiUrl}/ghosts/${encodeURIComponent(addrString)}/reputation`
|
|
158
|
+
);
|
|
159
|
+
if (response.status === 404) {
|
|
160
|
+
throw new GhostNotFoundError(addrString);
|
|
161
|
+
}
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
const error = await response.json().catch(() => ({}));
|
|
164
|
+
throw new GhostSpeakError(
|
|
165
|
+
error.message || "Failed to fetch reputation",
|
|
166
|
+
error.code || "FETCH_FAILED"
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return await response.json();
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (error instanceof GhostSpeakError || error instanceof GhostNotFoundError) throw error;
|
|
172
|
+
throw new GhostSpeakError(
|
|
173
|
+
"Failed to fetch reputation",
|
|
174
|
+
"FETCH_FAILED"
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Batch resolve multiple external IDs
|
|
180
|
+
*/
|
|
181
|
+
async resolveBatch(identifiers) {
|
|
182
|
+
const promises = identifiers.map(
|
|
183
|
+
({ platform, externalId }) => this.resolve(platform, externalId).catch(() => null)
|
|
184
|
+
);
|
|
185
|
+
return Promise.all(promises);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if external ID exists
|
|
189
|
+
*/
|
|
190
|
+
async exists(platform, externalId) {
|
|
191
|
+
try {
|
|
192
|
+
await this.resolve(platform, externalId);
|
|
193
|
+
return true;
|
|
194
|
+
} catch (error) {
|
|
195
|
+
if (error instanceof ExternalIdNotFoundError) return false;
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get all external IDs for a Ghost
|
|
201
|
+
*
|
|
202
|
+
* Fetches Ghost data and returns external identifiers
|
|
203
|
+
*/
|
|
204
|
+
async getExternalIds(ghostAddress) {
|
|
205
|
+
const ghost = await this.getGhost(ghostAddress);
|
|
206
|
+
return ghost.externalIdentifiers;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Search for Ghost by partial platform ID
|
|
210
|
+
*
|
|
211
|
+
* Note: This is a client-side filter, not server-side search
|
|
212
|
+
* For production, implement server-side search endpoint
|
|
213
|
+
*/
|
|
214
|
+
async searchByExternalId(platform, partialId) {
|
|
215
|
+
throw new GhostSpeakError(
|
|
216
|
+
"Search not yet implemented",
|
|
217
|
+
"NOT_IMPLEMENTED"
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Set custom API URL
|
|
222
|
+
*/
|
|
223
|
+
setApiUrl(apiUrl) {
|
|
224
|
+
this.apiUrl = apiUrl;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get current API URL
|
|
228
|
+
*/
|
|
229
|
+
getApiUrl() {
|
|
230
|
+
return this.apiUrl;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Check API health
|
|
234
|
+
*/
|
|
235
|
+
async checkHealth() {
|
|
236
|
+
try {
|
|
237
|
+
const response = await fetch(`${this.apiUrl}/health`);
|
|
238
|
+
if (!response.ok) {
|
|
239
|
+
throw new Error(`HTTP ${response.status}`);
|
|
240
|
+
}
|
|
241
|
+
return await response.json();
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new GhostSpeakError(
|
|
244
|
+
"Failed to check API health",
|
|
245
|
+
"HEALTH_CHECK_FAILED"
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// src/modules/escrow/EscrowModule.ts
|
|
252
|
+
var EscrowModule = class extends BaseModule {
|
|
253
|
+
/**
|
|
254
|
+
* Create a new escrow for a service agreement
|
|
255
|
+
*
|
|
256
|
+
* @param params - Escrow creation parameters
|
|
257
|
+
* @returns Transaction signature
|
|
258
|
+
*/
|
|
259
|
+
async createEscrow(params) {
|
|
260
|
+
const instruction = await getCreateEscrowInstructionAsync({
|
|
261
|
+
agent: params.agent,
|
|
262
|
+
clientTokenAccount: params.clientTokenAccount,
|
|
263
|
+
escrowVault: params.escrowVault,
|
|
264
|
+
tokenMint: params.tokenMint,
|
|
265
|
+
client: params.client,
|
|
266
|
+
escrowId: params.escrowId,
|
|
267
|
+
amount: params.amount,
|
|
268
|
+
jobDescription: params.jobDescription,
|
|
269
|
+
deadline: params.deadline
|
|
270
|
+
}, { programAddress: this.programId });
|
|
271
|
+
return this.execute("createEscrow", () => instruction, [params.client]);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Submit proof of delivery for an escrow
|
|
275
|
+
*
|
|
276
|
+
* @param params - Delivery submission parameters
|
|
277
|
+
* @returns Transaction signature
|
|
278
|
+
*/
|
|
279
|
+
async submitDelivery(params) {
|
|
280
|
+
const instruction = getSubmitDeliveryInstruction({
|
|
281
|
+
escrow: params.escrow,
|
|
282
|
+
agent: params.agent,
|
|
283
|
+
agentOwner: params.agentOwner,
|
|
284
|
+
deliveryProof: params.deliveryProof
|
|
285
|
+
}, { programAddress: this.programId });
|
|
286
|
+
return this.execute("submitDelivery", () => instruction, [params.agentOwner]);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Approve delivery and release funds to agent
|
|
290
|
+
*
|
|
291
|
+
* @param params - Approval parameters
|
|
292
|
+
* @returns Transaction signature
|
|
293
|
+
*/
|
|
294
|
+
async approveDelivery(params) {
|
|
295
|
+
const instruction = getApproveDeliveryInstruction({
|
|
296
|
+
escrow: params.escrow,
|
|
297
|
+
escrowVault: params.escrowVault,
|
|
298
|
+
agentTokenAccount: params.agentTokenAccount,
|
|
299
|
+
client: params.client
|
|
300
|
+
}, { programAddress: this.programId });
|
|
301
|
+
return this.execute("approveDelivery", () => instruction, [params.client]);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* File a dispute for an escrow
|
|
305
|
+
*
|
|
306
|
+
* @param params - Dispute filing parameters
|
|
307
|
+
* @returns Transaction signature
|
|
308
|
+
*/
|
|
309
|
+
async fileDispute(params) {
|
|
310
|
+
const instruction = getFileDisputeInstruction({
|
|
311
|
+
escrow: params.escrow,
|
|
312
|
+
client: params.client,
|
|
313
|
+
reason: params.reason
|
|
314
|
+
}, { programAddress: this.programId });
|
|
315
|
+
return this.execute("fileDispute", () => instruction, [params.client]);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Arbitrate a disputed escrow
|
|
319
|
+
*
|
|
320
|
+
* @param params - Arbitration parameters
|
|
321
|
+
* @returns Transaction signature
|
|
322
|
+
*/
|
|
323
|
+
async arbitrateDispute(params) {
|
|
324
|
+
const instruction = getArbitrateDisputeInstruction({
|
|
325
|
+
escrow: params.escrow,
|
|
326
|
+
escrowVault: params.escrowVault,
|
|
327
|
+
agentTokenAccount: params.agentTokenAccount,
|
|
328
|
+
clientTokenAccount: params.clientTokenAccount,
|
|
329
|
+
agentStaking: params.agentStaking,
|
|
330
|
+
arbitrator: params.arbitrator,
|
|
331
|
+
decision: params.decision
|
|
332
|
+
}, { programAddress: this.programId });
|
|
333
|
+
return this.execute("arbitrateDispute", () => instruction, [params.arbitrator]);
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Get escrow account data
|
|
337
|
+
*
|
|
338
|
+
* @param escrowAddress - The escrow account address
|
|
339
|
+
* @returns Escrow data or null if not found
|
|
340
|
+
*/
|
|
341
|
+
async getEscrow(escrowAddress) {
|
|
342
|
+
try {
|
|
343
|
+
return await this.getAccount(escrowAddress, "getGhostProtectEscrowDecoder");
|
|
344
|
+
} catch (error) {
|
|
345
|
+
console.error("Error fetching escrow:", error);
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// src/index.ts
|
|
37
352
|
init_reputation_tag_engine();
|
|
38
353
|
|
|
39
354
|
// src/modules/indexer/X402TransactionIndexer.ts
|
|
@@ -139,26 +454,37 @@ var X402TransactionIndexer = class {
|
|
|
139
454
|
* Check if transaction is an x402 payment
|
|
140
455
|
*
|
|
141
456
|
* x402 payments are characterized by:
|
|
142
|
-
* - SPL token transfer (TokenProgram or Token2022Program)
|
|
457
|
+
* - SPL token transfer (TokenProgram or Token2022Program) for USDC
|
|
458
|
+
* - Native SOL transfer (System Program)
|
|
143
459
|
* - Transfer TO the facilitator address
|
|
144
460
|
* - Optional memo instruction with payment metadata
|
|
461
|
+
*
|
|
462
|
+
* Supports both devnet and mainnet for all payment types
|
|
145
463
|
*/
|
|
146
464
|
isX402Payment(transaction) {
|
|
147
465
|
try {
|
|
148
466
|
const instructions = transaction.transaction?.message?.instructions || [];
|
|
149
|
-
const
|
|
467
|
+
const hasPaymentTransfer = instructions.some((ix) => {
|
|
150
468
|
const programId = ix.programId?.toString();
|
|
151
469
|
const isTokenProgram = programId === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" || // SPL Token
|
|
152
470
|
programId === "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
471
|
+
if (isTokenProgram) {
|
|
472
|
+
const parsed = ix.parsed;
|
|
473
|
+
if (parsed?.type === "transfer" || parsed?.type === "transferChecked") {
|
|
474
|
+
const destination = parsed.info?.destination;
|
|
475
|
+
return destination === this.facilitatorAddress.toString();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (programId === "11111111111111111111111111111111") {
|
|
479
|
+
const parsed = ix.parsed;
|
|
480
|
+
if (parsed?.type === "transfer") {
|
|
481
|
+
const destination = parsed.info?.destination;
|
|
482
|
+
return destination === this.facilitatorAddress.toString();
|
|
483
|
+
}
|
|
158
484
|
}
|
|
159
485
|
return false;
|
|
160
486
|
});
|
|
161
|
-
return
|
|
487
|
+
return hasPaymentTransfer;
|
|
162
488
|
} catch (error) {
|
|
163
489
|
console.error("[X402 Indexer] Error checking if x402 payment:", error);
|
|
164
490
|
return false;
|
|
@@ -172,7 +498,11 @@ var X402TransactionIndexer = class {
|
|
|
172
498
|
const instructions = transaction.transaction?.message?.instructions || [];
|
|
173
499
|
const transferIx = instructions.find((ix) => {
|
|
174
500
|
const parsed = ix.parsed;
|
|
175
|
-
|
|
501
|
+
const programId = ix.programId?.toString();
|
|
502
|
+
if (parsed?.type === "transfer" || parsed?.type === "transferChecked") {
|
|
503
|
+
return true;
|
|
504
|
+
}
|
|
505
|
+
return false;
|
|
176
506
|
});
|
|
177
507
|
if (!transferIx) {
|
|
178
508
|
return null;
|
|
@@ -180,7 +510,7 @@ var X402TransactionIndexer = class {
|
|
|
180
510
|
const transferInfo = transferIx.parsed.info;
|
|
181
511
|
const merchant = transferInfo.destination;
|
|
182
512
|
const payer = transferInfo.source;
|
|
183
|
-
const amount = transferInfo.amount || transferInfo.tokenAmount?.amount || "0";
|
|
513
|
+
const amount = transferInfo.amount || transferInfo.tokenAmount?.amount || transferInfo.lamports || "0";
|
|
184
514
|
const success = transaction.meta?.err === null;
|
|
185
515
|
const blockTime = transaction.blockTime;
|
|
186
516
|
const timestamp = blockTime ? new Date(blockTime * 1e3) : /* @__PURE__ */ new Date();
|
|
@@ -189,12 +519,21 @@ var X402TransactionIndexer = class {
|
|
|
189
519
|
);
|
|
190
520
|
let responseTimeMs;
|
|
191
521
|
let metadata;
|
|
192
|
-
if (memoIx
|
|
522
|
+
if (memoIx) {
|
|
193
523
|
try {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
524
|
+
let memoText;
|
|
525
|
+
if (memoIx.parsed) {
|
|
526
|
+
memoText = memoIx.parsed;
|
|
527
|
+
} else if (memoIx.data) {
|
|
528
|
+
memoText = Buffer.from(memoIx.data, "base64").toString("utf-8");
|
|
529
|
+
} else {
|
|
530
|
+
memoText = "";
|
|
531
|
+
}
|
|
532
|
+
if (memoText) {
|
|
533
|
+
const memoData = JSON.parse(memoText);
|
|
534
|
+
responseTimeMs = memoData.responseTimeMs;
|
|
535
|
+
metadata = memoData;
|
|
536
|
+
}
|
|
198
537
|
} catch {
|
|
199
538
|
}
|
|
200
539
|
}
|
|
@@ -219,510 +558,6 @@ var X402TransactionIndexer = class {
|
|
|
219
558
|
// src/index.ts
|
|
220
559
|
init_reputation_tags();
|
|
221
560
|
init_MultiSourceAggregator();
|
|
222
|
-
var TIMESTAMP_TOLERANCE_MS = 5 * 60 * 1e3;
|
|
223
|
-
var SIGNATURE_HEADER = "x-payai-signature";
|
|
224
|
-
var TIMESTAMP_HEADER = "x-payai-timestamp";
|
|
225
|
-
var PayAIWebhookHandler = class extends EventEmitter {
|
|
226
|
-
options;
|
|
227
|
-
verifySignatures;
|
|
228
|
-
authorizationModule;
|
|
229
|
-
payAIFacilitatorAddress;
|
|
230
|
-
constructor(options = {}, authorizationModule, payAIFacilitatorAddress) {
|
|
231
|
-
super();
|
|
232
|
-
this.options = options;
|
|
233
|
-
this.verifySignatures = options.verifySignatures ?? process.env.NODE_ENV === "production";
|
|
234
|
-
this.authorizationModule = authorizationModule;
|
|
235
|
-
this.payAIFacilitatorAddress = payAIFacilitatorAddress;
|
|
236
|
-
}
|
|
237
|
-
// =====================================================
|
|
238
|
-
// PUBLIC METHODS
|
|
239
|
-
// =====================================================
|
|
240
|
-
/**
|
|
241
|
-
* Handle an incoming webhook request
|
|
242
|
-
*
|
|
243
|
-
* @param request - The incoming HTTP request (must have headers and body)
|
|
244
|
-
* @returns Processing result
|
|
245
|
-
*/
|
|
246
|
-
async handleWebhook(request) {
|
|
247
|
-
try {
|
|
248
|
-
const payload = typeof request.body === "string" ? JSON.parse(request.body) : request.body;
|
|
249
|
-
if (this.verifySignatures && this.options.webhookSecret) {
|
|
250
|
-
const bodyStr = typeof request.body === "string" ? request.body : JSON.stringify(request.body);
|
|
251
|
-
const verification = await this.verifySignature(
|
|
252
|
-
request.headers,
|
|
253
|
-
bodyStr
|
|
254
|
-
);
|
|
255
|
-
if (!verification.valid) {
|
|
256
|
-
return {
|
|
257
|
-
success: false,
|
|
258
|
-
error: verification.error ?? "Invalid signature"
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
return await this.processPayload(payload);
|
|
263
|
-
} catch (error) {
|
|
264
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
265
|
-
this.emit("error", new Error(`Webhook processing failed: ${errorMessage}`));
|
|
266
|
-
return {
|
|
267
|
-
success: false,
|
|
268
|
-
error: errorMessage
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Verify webhook signature
|
|
274
|
-
*/
|
|
275
|
-
async verifySignature(headers, body) {
|
|
276
|
-
const getHeader = (name) => {
|
|
277
|
-
if (headers instanceof Headers) {
|
|
278
|
-
return headers.get(name) ?? void 0;
|
|
279
|
-
}
|
|
280
|
-
return headers[name];
|
|
281
|
-
};
|
|
282
|
-
const signature = getHeader(SIGNATURE_HEADER);
|
|
283
|
-
const timestamp = getHeader(TIMESTAMP_HEADER);
|
|
284
|
-
if (!signature) {
|
|
285
|
-
return { valid: false, error: "Missing signature header" };
|
|
286
|
-
}
|
|
287
|
-
if (!timestamp) {
|
|
288
|
-
return { valid: false, error: "Missing timestamp header" };
|
|
289
|
-
}
|
|
290
|
-
const timestampMs = parseInt(timestamp, 10);
|
|
291
|
-
if (isNaN(timestampMs)) {
|
|
292
|
-
return { valid: false, error: "Invalid timestamp format" };
|
|
293
|
-
}
|
|
294
|
-
const now = Date.now();
|
|
295
|
-
if (Math.abs(now - timestampMs) > TIMESTAMP_TOLERANCE_MS) {
|
|
296
|
-
return { valid: false, error: "Timestamp too old or too far in future" };
|
|
297
|
-
}
|
|
298
|
-
if (!this.options.webhookSecret) {
|
|
299
|
-
return { valid: false, error: "Webhook secret not configured" };
|
|
300
|
-
}
|
|
301
|
-
const expectedSignature = this.computeSignature(
|
|
302
|
-
timestamp,
|
|
303
|
-
body,
|
|
304
|
-
this.options.webhookSecret
|
|
305
|
-
);
|
|
306
|
-
const signatureBuffer = Buffer.from(signature, "hex");
|
|
307
|
-
const expectedBuffer = Buffer.from(expectedSignature, "hex");
|
|
308
|
-
if (signatureBuffer.length !== expectedBuffer.length) {
|
|
309
|
-
return { valid: false, error: "Invalid signature" };
|
|
310
|
-
}
|
|
311
|
-
if (!timingSafeEqual(signatureBuffer, expectedBuffer)) {
|
|
312
|
-
return { valid: false, error: "Invalid signature" };
|
|
313
|
-
}
|
|
314
|
-
return { valid: true };
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Convert a PayAI payment to a reputation record
|
|
318
|
-
*/
|
|
319
|
-
paymentToReputationRecord(data) {
|
|
320
|
-
return {
|
|
321
|
-
agentAddress: data.merchant,
|
|
322
|
-
paymentSignature: data.transactionSignature,
|
|
323
|
-
amount: BigInt(data.amount),
|
|
324
|
-
success: data.success ?? data.status === "settled",
|
|
325
|
-
responseTimeMs: data.responseTimeMs ?? 0,
|
|
326
|
-
payerAddress: data.payer,
|
|
327
|
-
timestamp: new Date(data.settledAt ?? data.verifiedAt ?? Date.now()),
|
|
328
|
-
network: data.network
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
// =====================================================
|
|
332
|
-
// PRIVATE METHODS
|
|
333
|
-
// =====================================================
|
|
334
|
-
/**
|
|
335
|
-
* Process a verified webhook payload
|
|
336
|
-
*/
|
|
337
|
-
async processPayload(payload) {
|
|
338
|
-
const { type, data } = payload;
|
|
339
|
-
switch (type) {
|
|
340
|
-
case "payment.verified":
|
|
341
|
-
this.emit("payment:verified", data);
|
|
342
|
-
await this.options.onPaymentVerified?.(data);
|
|
343
|
-
break;
|
|
344
|
-
case "payment.settled":
|
|
345
|
-
this.emit("payment:settled", data);
|
|
346
|
-
await this.options.onPaymentSettled?.(data);
|
|
347
|
-
if (this.options.onRecordReputation) {
|
|
348
|
-
if (this.authorizationModule && this.payAIFacilitatorAddress) {
|
|
349
|
-
const isAuthorized = await this.verifyOnChainAuthorization(data.merchant);
|
|
350
|
-
if (!isAuthorized) {
|
|
351
|
-
return {
|
|
352
|
-
success: false,
|
|
353
|
-
eventType: type,
|
|
354
|
-
paymentId: data.paymentId,
|
|
355
|
-
error: "Agent has not authorized PayAI facilitator to update reputation",
|
|
356
|
-
reputationRecorded: false
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
const record = this.paymentToReputationRecord(data);
|
|
361
|
-
await this.options.onRecordReputation(record);
|
|
362
|
-
this.emit("reputation:recorded", record);
|
|
363
|
-
return {
|
|
364
|
-
success: true,
|
|
365
|
-
eventType: type,
|
|
366
|
-
paymentId: data.paymentId,
|
|
367
|
-
reputationRecorded: true
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
break;
|
|
371
|
-
case "payment.failed":
|
|
372
|
-
this.emit("payment:failed", data);
|
|
373
|
-
await this.options.onPaymentFailed?.(data);
|
|
374
|
-
if (this.options.onRecordReputation) {
|
|
375
|
-
const record = this.paymentToReputationRecord(data);
|
|
376
|
-
record.success = false;
|
|
377
|
-
await this.options.onRecordReputation(record);
|
|
378
|
-
this.emit("reputation:recorded", record);
|
|
379
|
-
return {
|
|
380
|
-
success: true,
|
|
381
|
-
eventType: type,
|
|
382
|
-
paymentId: data.paymentId,
|
|
383
|
-
reputationRecorded: true
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
break;
|
|
387
|
-
case "payment.refunded":
|
|
388
|
-
break;
|
|
389
|
-
default:
|
|
390
|
-
return {
|
|
391
|
-
success: false,
|
|
392
|
-
error: `Unknown event type: ${type}`
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
return {
|
|
396
|
-
success: true,
|
|
397
|
-
eventType: type,
|
|
398
|
-
paymentId: data.paymentId,
|
|
399
|
-
reputationRecorded: false
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Verify on-chain authorization for an agent
|
|
404
|
-
*
|
|
405
|
-
* Checks if the agent has pre-authorized the PayAI facilitator
|
|
406
|
-
* to update their reputation on-chain.
|
|
407
|
-
*/
|
|
408
|
-
async verifyOnChainAuthorization(agentAddress) {
|
|
409
|
-
if (!this.authorizationModule || !this.payAIFacilitatorAddress) {
|
|
410
|
-
return true;
|
|
411
|
-
}
|
|
412
|
-
try {
|
|
413
|
-
const authorization = await this.authorizationModule.fetchAuthorization(
|
|
414
|
-
agentAddress,
|
|
415
|
-
this.payAIFacilitatorAddress
|
|
416
|
-
);
|
|
417
|
-
if (!authorization) {
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
420
|
-
const status = this.authorizationModule.getAuthorizationStatus(
|
|
421
|
-
authorization,
|
|
422
|
-
authorization.currentIndex
|
|
423
|
-
);
|
|
424
|
-
return status.isValid;
|
|
425
|
-
} catch (error) {
|
|
426
|
-
console.error("Failed to verify on-chain authorization:", error);
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Compute HMAC-SHA256 signature for a webhook payload
|
|
432
|
-
*/
|
|
433
|
-
computeSignature(timestamp, body, secret) {
|
|
434
|
-
const signedPayload = `${timestamp}.${body}`;
|
|
435
|
-
const hmac = createHmac("sha256", secret);
|
|
436
|
-
hmac.update(signedPayload);
|
|
437
|
-
return hmac.digest("hex");
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
function createPayAIWebhookHandler(options = {}) {
|
|
441
|
-
return new PayAIWebhookHandler(options);
|
|
442
|
-
}
|
|
443
|
-
function generateTestWebhookSignature(body, secret, timestamp) {
|
|
444
|
-
const ts = (timestamp ?? Date.now()).toString();
|
|
445
|
-
const signedPayload = `${ts}.${body}`;
|
|
446
|
-
const hmac = createHmac("sha256", secret);
|
|
447
|
-
hmac.update(signedPayload);
|
|
448
|
-
return {
|
|
449
|
-
signature: hmac.digest("hex"),
|
|
450
|
-
timestamp: ts
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
function createMockPayAIWebhook(overrides = {}) {
|
|
454
|
-
return {
|
|
455
|
-
id: `evt_${Date.now()}`,
|
|
456
|
-
type: "payment.settled",
|
|
457
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
458
|
-
data: {
|
|
459
|
-
paymentId: `pay_${Date.now()}`,
|
|
460
|
-
transactionSignature: `${Math.random().toString(36).slice(2)}${Math.random().toString(36).slice(2)}`,
|
|
461
|
-
network: "solana",
|
|
462
|
-
payer: "PayerWalletAddress111111111111111111111111",
|
|
463
|
-
merchant: "MerchantAgentAddress11111111111111111111",
|
|
464
|
-
amount: "1000000",
|
|
465
|
-
// 1 USDC
|
|
466
|
-
asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
467
|
-
assetSymbol: "USDC",
|
|
468
|
-
status: "settled",
|
|
469
|
-
resource: "https://api.example.com/ai/generate",
|
|
470
|
-
responseTimeMs: 250,
|
|
471
|
-
httpStatusCode: 200,
|
|
472
|
-
success: true,
|
|
473
|
-
settledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
474
|
-
...overrides
|
|
475
|
-
}
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
var DEFAULT_MARKETPLACE_URL = "https://marketplace.payai.network/api";
|
|
479
|
-
var PayAIAgentSync = class extends EventEmitter {
|
|
480
|
-
config;
|
|
481
|
-
constructor(config = {}) {
|
|
482
|
-
super();
|
|
483
|
-
this.config = {
|
|
484
|
-
marketplaceUrl: config.marketplaceUrl ?? DEFAULT_MARKETPLACE_URL,
|
|
485
|
-
apiKey: config.apiKey,
|
|
486
|
-
network: config.network ?? "solana",
|
|
487
|
-
timeout: config.timeout ?? 3e4
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
// =====================================================
|
|
491
|
-
// PUBLIC METHODS
|
|
492
|
-
// =====================================================
|
|
493
|
-
/**
|
|
494
|
-
* Register a GhostSpeak agent with PayAI marketplace
|
|
495
|
-
*
|
|
496
|
-
* @param agent - Agent data from GhostSpeak
|
|
497
|
-
* @returns Registration result
|
|
498
|
-
*/
|
|
499
|
-
async registerAgent(agent) {
|
|
500
|
-
try {
|
|
501
|
-
const registration = this.toPayAIRegistration(agent);
|
|
502
|
-
const response = await this.makeRequest("/merchants/register", {
|
|
503
|
-
method: "POST",
|
|
504
|
-
body: JSON.stringify(registration)
|
|
505
|
-
});
|
|
506
|
-
if (!response.ok) {
|
|
507
|
-
const error = await response.text();
|
|
508
|
-
return {
|
|
509
|
-
success: false,
|
|
510
|
-
error: `Registration failed: ${error}`
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
const data = await response.json();
|
|
514
|
-
this.emit("agent:registered", {
|
|
515
|
-
agentAddress: agent.address,
|
|
516
|
-
agentId: data.agentId
|
|
517
|
-
});
|
|
518
|
-
return {
|
|
519
|
-
success: true,
|
|
520
|
-
agentId: data.agentId,
|
|
521
|
-
marketplaceUrl: data.url
|
|
522
|
-
};
|
|
523
|
-
} catch (error) {
|
|
524
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
525
|
-
return {
|
|
526
|
-
success: false,
|
|
527
|
-
error: errorMessage
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* Update an agent's registration on PayAI marketplace
|
|
533
|
-
*
|
|
534
|
-
* @param agentId - PayAI agent ID
|
|
535
|
-
* @param agent - Updated agent data
|
|
536
|
-
* @returns Update result
|
|
537
|
-
*/
|
|
538
|
-
async updateAgent(agentId, agent) {
|
|
539
|
-
try {
|
|
540
|
-
const response = await this.makeRequest(`/merchants/${agentId}`, {
|
|
541
|
-
method: "PATCH",
|
|
542
|
-
body: JSON.stringify(agent)
|
|
543
|
-
});
|
|
544
|
-
if (!response.ok) {
|
|
545
|
-
const error = await response.text();
|
|
546
|
-
return {
|
|
547
|
-
success: false,
|
|
548
|
-
error: `Update failed: ${error}`
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
this.emit("agent:updated", { agentId });
|
|
552
|
-
return {
|
|
553
|
-
success: true,
|
|
554
|
-
agentId
|
|
555
|
-
};
|
|
556
|
-
} catch (error) {
|
|
557
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
558
|
-
return {
|
|
559
|
-
success: false,
|
|
560
|
-
error: errorMessage
|
|
561
|
-
};
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Remove an agent from PayAI marketplace
|
|
566
|
-
*
|
|
567
|
-
* @param agentId - PayAI agent ID
|
|
568
|
-
* @returns Removal result
|
|
569
|
-
*/
|
|
570
|
-
async removeAgent(agentId) {
|
|
571
|
-
try {
|
|
572
|
-
const response = await this.makeRequest(`/merchants/${agentId}`, {
|
|
573
|
-
method: "DELETE"
|
|
574
|
-
});
|
|
575
|
-
if (!response.ok) {
|
|
576
|
-
const error = await response.text();
|
|
577
|
-
return {
|
|
578
|
-
success: false,
|
|
579
|
-
error: `Removal failed: ${error}`
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
this.emit("agent:removed", { agentId });
|
|
583
|
-
return {
|
|
584
|
-
success: true,
|
|
585
|
-
agentId
|
|
586
|
-
};
|
|
587
|
-
} catch (error) {
|
|
588
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
589
|
-
return {
|
|
590
|
-
success: false,
|
|
591
|
-
error: errorMessage
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Check if an agent is registered on PayAI marketplace
|
|
597
|
-
*
|
|
598
|
-
* @param agentAddress - Agent's Solana address
|
|
599
|
-
* @returns Whether agent is registered
|
|
600
|
-
*/
|
|
601
|
-
async isAgentRegistered(agentAddress) {
|
|
602
|
-
try {
|
|
603
|
-
const response = await this.makeRequest(
|
|
604
|
-
`/merchants/check?address=${agentAddress}&network=${this.config.network}`
|
|
605
|
-
);
|
|
606
|
-
if (!response.ok) {
|
|
607
|
-
return false;
|
|
608
|
-
}
|
|
609
|
-
const data = await response.json();
|
|
610
|
-
return data.registered;
|
|
611
|
-
} catch {
|
|
612
|
-
return false;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Get agent's PayAI marketplace listing
|
|
617
|
-
*
|
|
618
|
-
* @param agentAddress - Agent's Solana address
|
|
619
|
-
* @returns Agent listing or null
|
|
620
|
-
*/
|
|
621
|
-
async getAgentListing(agentAddress) {
|
|
622
|
-
try {
|
|
623
|
-
const response = await this.makeRequest(
|
|
624
|
-
`/merchants/by-address?address=${agentAddress}&network=${this.config.network}`
|
|
625
|
-
);
|
|
626
|
-
if (!response.ok) {
|
|
627
|
-
return null;
|
|
628
|
-
}
|
|
629
|
-
return response.json();
|
|
630
|
-
} catch {
|
|
631
|
-
return null;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Sync reputation score to PayAI marketplace
|
|
636
|
-
*
|
|
637
|
-
* Updates the agent's reputation score on PayAI based on
|
|
638
|
-
* GhostSpeak reputation calculations.
|
|
639
|
-
*
|
|
640
|
-
* @param agentId - PayAI agent ID
|
|
641
|
-
* @param reputationScore - New reputation score (0-10000)
|
|
642
|
-
* @returns Update result
|
|
643
|
-
*/
|
|
644
|
-
async syncReputationScore(agentId, reputationScore) {
|
|
645
|
-
try {
|
|
646
|
-
const response = await this.makeRequest(`/merchants/${agentId}/reputation`, {
|
|
647
|
-
method: "POST",
|
|
648
|
-
body: JSON.stringify({
|
|
649
|
-
score: reputationScore,
|
|
650
|
-
source: "ghostspeak",
|
|
651
|
-
timestamp: Date.now()
|
|
652
|
-
})
|
|
653
|
-
});
|
|
654
|
-
if (!response.ok) {
|
|
655
|
-
const error = await response.text();
|
|
656
|
-
return {
|
|
657
|
-
success: false,
|
|
658
|
-
error: `Reputation sync failed: ${error}`
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
this.emit("reputation:synced", { agentId, reputationScore });
|
|
662
|
-
return {
|
|
663
|
-
success: true,
|
|
664
|
-
agentId
|
|
665
|
-
};
|
|
666
|
-
} catch (error) {
|
|
667
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
668
|
-
return {
|
|
669
|
-
success: false,
|
|
670
|
-
error: errorMessage
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
// =====================================================
|
|
675
|
-
// PRIVATE METHODS
|
|
676
|
-
// =====================================================
|
|
677
|
-
/**
|
|
678
|
-
* Convert GhostSpeak agent data to PayAI registration format
|
|
679
|
-
*/
|
|
680
|
-
toPayAIRegistration(agent) {
|
|
681
|
-
return {
|
|
682
|
-
agentAddress: agent.address,
|
|
683
|
-
serviceEndpoint: agent.serviceEndpoint,
|
|
684
|
-
capabilities: agent.capabilities,
|
|
685
|
-
acceptedTokens: agent.acceptedTokens,
|
|
686
|
-
pricing: agent.pricing,
|
|
687
|
-
metadata: {
|
|
688
|
-
name: agent.name,
|
|
689
|
-
description: agent.description,
|
|
690
|
-
logo: agent.logo,
|
|
691
|
-
website: agent.website
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
}
|
|
695
|
-
/**
|
|
696
|
-
* Make an authenticated request to PayAI marketplace
|
|
697
|
-
*/
|
|
698
|
-
async makeRequest(path, options = {}) {
|
|
699
|
-
const controller = new AbortController();
|
|
700
|
-
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
701
|
-
const headers = {
|
|
702
|
-
"Content-Type": "application/json",
|
|
703
|
-
"X-Ghostspeak-Integration": "1.0"
|
|
704
|
-
};
|
|
705
|
-
if (this.config.apiKey) {
|
|
706
|
-
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
707
|
-
}
|
|
708
|
-
try {
|
|
709
|
-
const response = await fetch(`${this.config.marketplaceUrl}${path}`, {
|
|
710
|
-
...options,
|
|
711
|
-
headers: {
|
|
712
|
-
...headers,
|
|
713
|
-
...options.headers
|
|
714
|
-
},
|
|
715
|
-
signal: controller.signal
|
|
716
|
-
});
|
|
717
|
-
return response;
|
|
718
|
-
} finally {
|
|
719
|
-
clearTimeout(timeoutId);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
};
|
|
723
|
-
function createPayAIAgentSync(config = {}) {
|
|
724
|
-
return new PayAIAgentSync(config);
|
|
725
|
-
}
|
|
726
561
|
|
|
727
562
|
// src/utils/test-ipfs-config.ts
|
|
728
563
|
var TEST_IPFS_CONFIG = {
|
|
@@ -2346,6 +2181,6 @@ function clearFeatureGateCache() {
|
|
|
2346
2181
|
featureCache.clear();
|
|
2347
2182
|
}
|
|
2348
2183
|
|
|
2349
|
-
export { CircuitBreaker, DEFAULT_RETRY_CONFIG, FEATURE_GATES, FallbackHandler, IPFSErrorHandler, IPFSOperationError, IPFSProvider, LocalStorageProvider,
|
|
2184
|
+
export { CircuitBreaker, DEFAULT_RETRY_CONFIG, EscrowModule, ExternalIdResolver, FEATURE_GATES, FallbackHandler, IPFSErrorHandler, IPFSOperationError, IPFSProvider, LocalStorageProvider, PrivateDataQuery, PrivateMetadataStorage, RetryHandler, TEST_IPFS_CONFIG, WalletFundingService, X402TransactionIndexer, checkFeatureGate, clearFeatureGateCache, createIPFSErrorHandler, createPrivacyManifest, createTestIPFSConfig, defaultFundingService, ensureMinimumBalance, estimateStorageCost, fundWallet, isIPFSError, withIPFSErrorHandling };
|
|
2350
2185
|
//# sourceMappingURL=index.js.map
|
|
2351
2186
|
//# sourceMappingURL=index.js.map
|