@agirails/sdk 2.2.3 → 2.3.1
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 +65 -31
- package/dist/ACTPClient.d.ts +42 -1
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +207 -22
- package/dist/ACTPClient.js.map +1 -1
- package/dist/abi/AgentRegistry.json +133 -0
- package/dist/adapters/AdapterRouter.d.ts.map +1 -1
- package/dist/adapters/AdapterRouter.js.map +1 -1
- package/dist/adapters/BasicAdapter.d.ts +10 -1
- package/dist/adapters/BasicAdapter.d.ts.map +1 -1
- package/dist/adapters/BasicAdapter.js +36 -1
- package/dist/adapters/BasicAdapter.js.map +1 -1
- package/dist/adapters/X402Adapter.d.ts +34 -7
- package/dist/adapters/X402Adapter.d.ts.map +1 -1
- package/dist/adapters/X402Adapter.js +36 -8
- package/dist/adapters/X402Adapter.js.map +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/cli/commands/diff.d.ts +11 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +115 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +260 -19
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/publish.d.ts +11 -0
- package/dist/cli/commands/publish.d.ts.map +1 -0
- package/dist/cli/commands/publish.js +170 -0
- package/dist/cli/commands/publish.js.map +1 -0
- package/dist/cli/commands/pull.d.ts +12 -0
- package/dist/cli/commands/pull.d.ts.map +1 -0
- package/dist/cli/commands/pull.js +99 -0
- package/dist/cli/commands/pull.js.map +1 -0
- package/dist/cli/commands/register.d.ts +16 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +211 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/config.d.ts +6 -0
- package/dist/cli/utils/config.d.ts.map +1 -1
- package/dist/cli/utils/config.js.map +1 -1
- package/dist/config/agirailsmd.d.ts +94 -0
- package/dist/config/agirailsmd.d.ts.map +1 -0
- package/dist/config/agirailsmd.js +209 -0
- package/dist/config/agirailsmd.js.map +1 -0
- package/dist/config/networks.d.ts +22 -4
- package/dist/config/networks.d.ts.map +1 -1
- package/dist/config/networks.js +64 -26
- package/dist/config/networks.js.map +1 -1
- package/dist/config/publishPipeline.d.ts +75 -0
- package/dist/config/publishPipeline.d.ts.map +1 -0
- package/dist/config/publishPipeline.js +193 -0
- package/dist/config/publishPipeline.js.map +1 -0
- package/dist/config/syncOperations.d.ts +67 -0
- package/dist/config/syncOperations.d.ts.map +1 -0
- package/dist/config/syncOperations.js +208 -0
- package/dist/config/syncOperations.js.map +1 -0
- package/dist/erc8004/ERC8004Bridge.d.ts.map +1 -1
- package/dist/erc8004/ERC8004Bridge.js +6 -5
- package/dist/erc8004/ERC8004Bridge.js.map +1 -1
- package/dist/erc8004/ReputationReporter.d.ts.map +1 -1
- package/dist/erc8004/ReputationReporter.js +9 -12
- package/dist/erc8004/ReputationReporter.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/index.js.map +1 -1
- package/dist/level0/request.d.ts.map +1 -1
- package/dist/level0/request.js +23 -86
- package/dist/level0/request.js.map +1 -1
- package/dist/level1/Agent.d.ts +0 -11
- package/dist/level1/Agent.d.ts.map +1 -1
- package/dist/level1/Agent.js +19 -36
- package/dist/level1/Agent.js.map +1 -1
- package/dist/protocol/ACTPKernel.d.ts +7 -1
- package/dist/protocol/ACTPKernel.d.ts.map +1 -1
- package/dist/protocol/ACTPKernel.js +13 -10
- package/dist/protocol/ACTPKernel.js.map +1 -1
- package/dist/protocol/EventMonitor.d.ts +14 -0
- package/dist/protocol/EventMonitor.d.ts.map +1 -1
- package/dist/protocol/EventMonitor.js +14 -0
- package/dist/protocol/EventMonitor.js.map +1 -1
- package/dist/registry/AgentRegistryClient.d.ts +75 -0
- package/dist/registry/AgentRegistryClient.d.ts.map +1 -0
- package/dist/registry/AgentRegistryClient.js +160 -0
- package/dist/registry/AgentRegistryClient.js.map +1 -0
- package/dist/runtime/BlockchainRuntime.d.ts +5 -0
- package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
- package/dist/runtime/BlockchainRuntime.js +1 -1
- package/dist/runtime/BlockchainRuntime.js.map +1 -1
- package/dist/storage/ArchiveBundleBuilder.d.ts.map +1 -1
- package/dist/storage/ArchiveBundleBuilder.js.map +1 -1
- package/dist/storage/ArweaveClient.d.ts.map +1 -1
- package/dist/storage/ArweaveClient.js +2 -0
- package/dist/storage/ArweaveClient.js.map +1 -1
- package/dist/storage/FilebaseClient.d.ts.map +1 -1
- package/dist/storage/FilebaseClient.js +2 -0
- package/dist/storage/FilebaseClient.js.map +1 -1
- package/dist/types/adapter.d.ts +39 -0
- package/dist/types/adapter.d.ts.map +1 -1
- package/dist/types/adapter.js +7 -0
- package/dist/types/adapter.js.map +1 -1
- package/dist/types/x402.d.ts +23 -0
- package/dist/types/x402.d.ts.map +1 -1
- package/dist/types/x402.js.map +1 -1
- package/dist/utils/ErrorRecoveryGuide.d.ts.map +1 -1
- package/dist/utils/ErrorRecoveryGuide.js +3 -2
- package/dist/utils/ErrorRecoveryGuide.js.map +1 -1
- package/dist/utils/IPFSClient.d.ts +3 -2
- package/dist/utils/IPFSClient.d.ts.map +1 -1
- package/dist/utils/IPFSClient.js +7 -5
- package/dist/utils/IPFSClient.js.map +1 -1
- package/dist/utils/computeTypeHash.js +1 -3
- package/dist/utils/computeTypeHash.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +0 -1
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/validation.d.ts +2 -2
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +2 -2
- package/dist/utils/validation.js.map +1 -1
- package/dist/wallet/AutoWalletProvider.d.ts +77 -0
- package/dist/wallet/AutoWalletProvider.d.ts.map +1 -0
- package/dist/wallet/AutoWalletProvider.js +197 -0
- package/dist/wallet/AutoWalletProvider.js.map +1 -0
- package/dist/wallet/EOAWalletProvider.d.ts +21 -0
- package/dist/wallet/EOAWalletProvider.d.ts.map +1 -0
- package/dist/wallet/EOAWalletProvider.js +57 -0
- package/dist/wallet/EOAWalletProvider.js.map +1 -0
- package/dist/wallet/IWalletProvider.d.ts +115 -0
- package/dist/wallet/IWalletProvider.d.ts.map +1 -0
- package/dist/wallet/IWalletProvider.js +12 -0
- package/dist/wallet/IWalletProvider.js.map +1 -0
- package/dist/wallet/aa/BundlerClient.d.ts +70 -0
- package/dist/wallet/aa/BundlerClient.d.ts.map +1 -0
- package/dist/wallet/aa/BundlerClient.js +183 -0
- package/dist/wallet/aa/BundlerClient.js.map +1 -0
- package/dist/wallet/aa/DualNonceManager.d.ts +55 -0
- package/dist/wallet/aa/DualNonceManager.d.ts.map +1 -0
- package/dist/wallet/aa/DualNonceManager.js +131 -0
- package/dist/wallet/aa/DualNonceManager.js.map +1 -0
- package/dist/wallet/aa/PaymasterClient.d.ts +52 -0
- package/dist/wallet/aa/PaymasterClient.d.ts.map +1 -0
- package/dist/wallet/aa/PaymasterClient.js +115 -0
- package/dist/wallet/aa/PaymasterClient.js.map +1 -0
- package/dist/wallet/aa/TransactionBatcher.d.ts +87 -0
- package/dist/wallet/aa/TransactionBatcher.d.ts.map +1 -0
- package/dist/wallet/aa/TransactionBatcher.js +148 -0
- package/dist/wallet/aa/TransactionBatcher.js.map +1 -0
- package/dist/wallet/aa/UserOpBuilder.d.ts +71 -0
- package/dist/wallet/aa/UserOpBuilder.d.ts.map +1 -0
- package/dist/wallet/aa/UserOpBuilder.js +196 -0
- package/dist/wallet/aa/UserOpBuilder.js.map +1 -0
- package/dist/wallet/aa/constants.d.ts +54 -0
- package/dist/wallet/aa/constants.d.ts.map +1 -0
- package/dist/wallet/aa/constants.js +18 -0
- package/dist/wallet/aa/constants.js.map +1 -0
- package/dist/wallet/keystore.d.ts +16 -0
- package/dist/wallet/keystore.d.ts.map +1 -0
- package/dist/wallet/keystore.js +132 -0
- package/dist/wallet/keystore.js.map +1 -0
- package/package.json +5 -2
- package/src/ACTPClient.ts +275 -27
- package/src/abi/AgentRegistry.json +133 -0
- package/src/adapters/AdapterRouter.ts +0 -1
- package/src/adapters/BasicAdapter.ts +41 -1
- package/src/adapters/X402Adapter.ts +94 -16
- package/src/adapters/index.ts +9 -1
- package/src/cli/commands/diff.ts +141 -0
- package/src/cli/commands/init.ts +311 -22
- package/src/cli/commands/publish.ts +208 -0
- package/src/cli/commands/pull.ts +124 -0
- package/src/cli/commands/register.ts +233 -0
- package/src/cli/index.ts +12 -0
- package/src/cli/utils/config.ts +9 -0
- package/src/config/agirailsmd.ts +262 -0
- package/src/config/networks.ts +89 -26
- package/src/config/publishPipeline.ts +276 -0
- package/src/config/syncOperations.ts +279 -0
- package/src/erc8004/ERC8004Bridge.ts +6 -5
- package/src/erc8004/ReputationReporter.ts +14 -18
- package/src/index.ts +15 -0
- package/src/level0/request.ts +27 -88
- package/src/level1/Agent.ts +21 -37
- package/src/protocol/ACTPKernel.ts +20 -10
- package/src/protocol/EventMonitor.ts +14 -0
- package/src/registry/AgentRegistryClient.ts +202 -0
- package/src/runtime/BlockchainRuntime.ts +7 -1
- package/src/storage/ArchiveBundleBuilder.ts +0 -2
- package/src/storage/ArweaveClient.ts +2 -1
- package/src/storage/FilebaseClient.ts +3 -3
- package/src/types/adapter.ts +14 -0
- package/src/types/x402.ts +32 -0
- package/src/utils/ErrorRecoveryGuide.ts +4 -2
- package/src/utils/IPFSClient.ts +9 -7
- package/src/utils/computeTypeHash.ts +1 -3
- package/src/utils/retry.ts +0 -1
- package/src/utils/validation.ts +2 -2
- package/src/wallet/AutoWalletProvider.ts +294 -0
- package/src/wallet/EOAWalletProvider.ts +69 -0
- package/src/wallet/IWalletProvider.ts +133 -0
- package/src/wallet/aa/BundlerClient.ts +273 -0
- package/src/wallet/aa/DualNonceManager.ts +163 -0
- package/src/wallet/aa/PaymasterClient.ts +173 -0
- package/src/wallet/aa/TransactionBatcher.ts +240 -0
- package/src/wallet/aa/UserOpBuilder.ts +246 -0
- package/src/wallet/aa/constants.ts +60 -0
- package/src/wallet/keystore.ts +119 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentRegistryClient - Thin wrapper for AgentRegistry v2 config operations
|
|
3
|
+
*
|
|
4
|
+
* Provides methods for:
|
|
5
|
+
* - Publishing AGIRAILS.md config (CID + hash) on-chain
|
|
6
|
+
* - Managing launchpad listing visibility
|
|
7
|
+
* - Reading config state for any agent
|
|
8
|
+
*
|
|
9
|
+
* @module registry/AgentRegistryClient
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Contract, Signer, Provider } from 'ethers';
|
|
13
|
+
import AgentRegistryABI from '../abi/AgentRegistry.json';
|
|
14
|
+
import { ValidationError, TransactionRevertedError } from '../errors';
|
|
15
|
+
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Types
|
|
18
|
+
// ============================================================================
|
|
19
|
+
|
|
20
|
+
export interface AgentConfigState {
|
|
21
|
+
configHash: string;
|
|
22
|
+
configCID: string;
|
|
23
|
+
listed: boolean;
|
|
24
|
+
isActive: boolean;
|
|
25
|
+
updatedAt: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface PublishConfigResult {
|
|
29
|
+
txHash: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface GasOptions {
|
|
33
|
+
maxFeePerGas?: bigint;
|
|
34
|
+
maxPriorityFeePerGas?: bigint;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Client
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
export class AgentRegistryClient {
|
|
42
|
+
private contract: Contract;
|
|
43
|
+
private readonlyContract: Contract;
|
|
44
|
+
|
|
45
|
+
constructor(
|
|
46
|
+
private readonly registryAddress: string,
|
|
47
|
+
private readonly signer: Signer,
|
|
48
|
+
private readonly gasSettings?: GasOptions
|
|
49
|
+
) {
|
|
50
|
+
this.contract = new Contract(registryAddress, AgentRegistryABI, signer);
|
|
51
|
+
this.readonlyContract = this.contract;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create a read-only client (no signer required)
|
|
56
|
+
*/
|
|
57
|
+
static readOnly(registryAddress: string, provider: Provider): AgentRegistryClient {
|
|
58
|
+
// Create a minimal signer-like object for the contract
|
|
59
|
+
// but only the readonly contract will be used
|
|
60
|
+
const contract = new Contract(registryAddress, AgentRegistryABI, provider);
|
|
61
|
+
const client = Object.create(AgentRegistryClient.prototype);
|
|
62
|
+
client.registryAddress = registryAddress;
|
|
63
|
+
client.readonlyContract = contract;
|
|
64
|
+
client.contract = null; // Write operations will throw
|
|
65
|
+
return client;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ========== WRITE OPERATIONS ==========
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Publish config (AGIRAILS.md) on-chain
|
|
72
|
+
*
|
|
73
|
+
* @param cid - IPFS CID pointing to the AGIRAILS.md file
|
|
74
|
+
* @param hash - keccak256 of canonical AGIRAILS.md content (bytes32)
|
|
75
|
+
* @returns Transaction hash
|
|
76
|
+
*/
|
|
77
|
+
async publishConfig(cid: string, hash: string): Promise<PublishConfigResult> {
|
|
78
|
+
if (!this.contract) {
|
|
79
|
+
throw new Error('Write operations require a signer. Use AgentRegistryClient constructor, not readOnly().');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!cid || cid.length === 0) {
|
|
83
|
+
throw new ValidationError('cid', 'IPFS CID is required');
|
|
84
|
+
}
|
|
85
|
+
if (cid.length > 128) {
|
|
86
|
+
throw new ValidationError('cid', 'CID too long (max 128 characters)');
|
|
87
|
+
}
|
|
88
|
+
if (!hash || hash === '0x' + '0'.repeat(64)) {
|
|
89
|
+
throw new ValidationError('hash', 'Config hash is required (cannot be zero)');
|
|
90
|
+
}
|
|
91
|
+
if (!/^0x[a-fA-F0-9]{64}$/.test(hash)) {
|
|
92
|
+
throw new ValidationError('hash', 'Config hash must be a valid bytes32 hex string');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const estimatedGas = await this.contract.publishConfig.estimateGas(cid, hash);
|
|
97
|
+
const gasLimit = (estimatedGas * 120n) / 100n; // 20% buffer
|
|
98
|
+
|
|
99
|
+
const txOptions: Record<string, unknown> = { gasLimit };
|
|
100
|
+
if (this.gasSettings?.maxFeePerGas) {
|
|
101
|
+
txOptions.maxFeePerGas = this.gasSettings.maxFeePerGas;
|
|
102
|
+
}
|
|
103
|
+
if (this.gasSettings?.maxPriorityFeePerGas) {
|
|
104
|
+
txOptions.maxPriorityFeePerGas = this.gasSettings.maxPriorityFeePerGas;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const tx = await this.contract.publishConfig(cid, hash, txOptions);
|
|
108
|
+
const receipt = await tx.wait();
|
|
109
|
+
|
|
110
|
+
return { txHash: receipt.hash };
|
|
111
|
+
} catch (error: unknown) {
|
|
112
|
+
if (error instanceof Error && error.message.includes('Not registered')) {
|
|
113
|
+
throw new TransactionRevertedError(
|
|
114
|
+
'Agent not registered. Register first using the AgentRegistry before publishing config.',
|
|
115
|
+
'publishConfig'
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Set launchpad listing visibility
|
|
124
|
+
*
|
|
125
|
+
* @param listed - Whether agent should be visible on launchpad
|
|
126
|
+
* @returns Transaction hash
|
|
127
|
+
*/
|
|
128
|
+
async setListed(listed: boolean): Promise<string> {
|
|
129
|
+
if (!this.contract) {
|
|
130
|
+
throw new Error('Write operations require a signer. Use AgentRegistryClient constructor, not readOnly().');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const estimatedGas = await this.contract.setListed.estimateGas(listed);
|
|
135
|
+
const gasLimit = (estimatedGas * 115n) / 100n; // 15% buffer
|
|
136
|
+
|
|
137
|
+
const txOptions: Record<string, unknown> = { gasLimit };
|
|
138
|
+
if (this.gasSettings?.maxFeePerGas) {
|
|
139
|
+
txOptions.maxFeePerGas = this.gasSettings.maxFeePerGas;
|
|
140
|
+
}
|
|
141
|
+
if (this.gasSettings?.maxPriorityFeePerGas) {
|
|
142
|
+
txOptions.maxPriorityFeePerGas = this.gasSettings.maxPriorityFeePerGas;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const tx = await this.contract.setListed(listed, txOptions);
|
|
146
|
+
const receipt = await tx.wait();
|
|
147
|
+
|
|
148
|
+
return receipt.hash;
|
|
149
|
+
} catch (error: unknown) {
|
|
150
|
+
if (error instanceof Error && error.message.includes('Not registered')) {
|
|
151
|
+
throw new TransactionRevertedError(
|
|
152
|
+
'Agent not registered. Register first before setting listing status.',
|
|
153
|
+
'setListed'
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ========== READ OPERATIONS ==========
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Get config state for an agent
|
|
164
|
+
*
|
|
165
|
+
* @param agentAddress - Agent's Ethereum address
|
|
166
|
+
* @returns Config state (hash, CID, listed, isActive, updatedAt)
|
|
167
|
+
*/
|
|
168
|
+
async getConfig(agentAddress: string): Promise<AgentConfigState> {
|
|
169
|
+
const contract = this.readonlyContract || this.contract;
|
|
170
|
+
const profile = await contract.getAgent(agentAddress);
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
configHash: profile.configHash,
|
|
174
|
+
configCID: profile.configCID,
|
|
175
|
+
listed: profile.listed,
|
|
176
|
+
isActive: profile.isActive,
|
|
177
|
+
updatedAt: Number(profile.updatedAt),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Check if an agent is listed on the launchpad
|
|
183
|
+
*
|
|
184
|
+
* @param agentAddress - Agent's Ethereum address
|
|
185
|
+
* @returns true if agent is listed
|
|
186
|
+
*/
|
|
187
|
+
async isListed(agentAddress: string): Promise<boolean> {
|
|
188
|
+
const config = await this.getConfig(agentAddress);
|
|
189
|
+
return config.listed;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get the on-chain config hash for an agent
|
|
194
|
+
*
|
|
195
|
+
* @param agentAddress - Agent's Ethereum address
|
|
196
|
+
* @returns Config hash (bytes32) or zero hash if not published
|
|
197
|
+
*/
|
|
198
|
+
async getConfigHash(agentAddress: string): Promise<string> {
|
|
199
|
+
const config = await this.getConfig(agentAddress);
|
|
200
|
+
return config.configHash;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -65,6 +65,11 @@ export interface BlockchainRuntimeConfig {
|
|
|
65
65
|
* If provided, attestation replay protection will survive restarts
|
|
66
66
|
*/
|
|
67
67
|
stateDirectory?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Number of block confirmations to wait after each state-changing tx.
|
|
70
|
+
* Default: 2 (Base L2 reorg safety). Set to 1 on testnet for speed.
|
|
71
|
+
*/
|
|
72
|
+
confirmations?: number;
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
/**
|
|
@@ -163,7 +168,8 @@ export class BlockchainRuntime implements IACTPRuntime {
|
|
|
163
168
|
this.kernel = new ACTPKernel(
|
|
164
169
|
this.networkConfig.contracts.actpKernel,
|
|
165
170
|
this.signer,
|
|
166
|
-
config.gasSettings
|
|
171
|
+
config.gasSettings,
|
|
172
|
+
config.confirmations
|
|
167
173
|
);
|
|
168
174
|
|
|
169
175
|
this.escrow = new EscrowVault(
|
|
@@ -15,14 +15,12 @@ import { ValidationError } from '../errors';
|
|
|
15
15
|
import {
|
|
16
16
|
ArchiveBundle,
|
|
17
17
|
ArchiveChainId,
|
|
18
|
-
ArchiveFinalState,
|
|
19
18
|
ArchiveParticipants,
|
|
20
19
|
ArchiveReferences,
|
|
21
20
|
ArchiveHashes,
|
|
22
21
|
ArchiveSignatures,
|
|
23
22
|
ArchiveAttestation,
|
|
24
23
|
ArchiveSettlement,
|
|
25
|
-
EscrowRelease,
|
|
26
24
|
ARCHIVE_BUNDLE_TYPE
|
|
27
25
|
} from './types';
|
|
28
26
|
|
|
@@ -48,7 +48,6 @@ import {
|
|
|
48
48
|
import { withRetry, RetryOptions } from '../utils/retry';
|
|
49
49
|
import {
|
|
50
50
|
GatewayCircuitBreaker,
|
|
51
|
-
CircuitBreakerConfig
|
|
52
51
|
} from '../utils/circuitBreaker';
|
|
53
52
|
|
|
54
53
|
// ============================================================================
|
|
@@ -538,6 +537,7 @@ export class ArweaveClient {
|
|
|
538
537
|
const chunks: Uint8Array[] = [];
|
|
539
538
|
let totalSize = 0;
|
|
540
539
|
|
|
540
|
+
// eslint-disable-next-line no-constant-condition
|
|
541
541
|
while (true) {
|
|
542
542
|
const { done, value } = await reader.read();
|
|
543
543
|
if (done) break;
|
|
@@ -671,6 +671,7 @@ export class ArweaveClient {
|
|
|
671
671
|
const chunks: Uint8Array[] = [];
|
|
672
672
|
let totalSize = 0;
|
|
673
673
|
|
|
674
|
+
// eslint-disable-next-line no-constant-condition
|
|
674
675
|
while (true) {
|
|
675
676
|
const { done, value } = await reader.read();
|
|
676
677
|
if (done) break;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @module storage/FilebaseClient
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { S3Client, PutObjectCommand,
|
|
17
|
+
import { S3Client, PutObjectCommand, HeadObjectCommand } from '@aws-sdk/client-s3';
|
|
18
18
|
import {
|
|
19
19
|
StorageError,
|
|
20
20
|
StorageAuthenticationError,
|
|
@@ -39,8 +39,6 @@ import {
|
|
|
39
39
|
import { withRetry, RetryOptions } from '../utils/retry';
|
|
40
40
|
import {
|
|
41
41
|
GatewayCircuitBreaker,
|
|
42
|
-
CircuitBreakerConfig,
|
|
43
|
-
globalCircuitBreaker
|
|
44
42
|
} from '../utils/circuitBreaker';
|
|
45
43
|
|
|
46
44
|
// ============================================================================
|
|
@@ -329,6 +327,7 @@ export class FilebaseClient {
|
|
|
329
327
|
const chunks: Uint8Array[] = [];
|
|
330
328
|
let totalSize = 0;
|
|
331
329
|
|
|
330
|
+
// eslint-disable-next-line no-constant-condition
|
|
332
331
|
while (true) {
|
|
333
332
|
const { done, value } = await reader.read();
|
|
334
333
|
if (done) break;
|
|
@@ -516,6 +515,7 @@ export class FilebaseClient {
|
|
|
516
515
|
const chunks: Uint8Array[] = [];
|
|
517
516
|
let totalSize = 0;
|
|
518
517
|
|
|
518
|
+
// eslint-disable-next-line no-constant-condition
|
|
519
519
|
while (true) {
|
|
520
520
|
const { done, value } = await reader.read();
|
|
521
521
|
if (done) break;
|
package/src/types/adapter.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { z } from 'zod';
|
|
14
|
+
import type { X402FeeBreakdown } from './x402';
|
|
14
15
|
|
|
15
16
|
// ============================================================================
|
|
16
17
|
// AdapterMetadata - Describes adapter capabilities
|
|
@@ -249,6 +250,12 @@ export interface UnifiedPayResult {
|
|
|
249
250
|
* Use with ReputationReporter.reportSettlement() after release.
|
|
250
251
|
*/
|
|
251
252
|
erc8004AgentId?: string;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Fee breakdown for x402 payments routed through X402Relay.
|
|
256
|
+
* Present only when relay is configured and payment used the relay path.
|
|
257
|
+
*/
|
|
258
|
+
feeBreakdown?: X402FeeBreakdown;
|
|
252
259
|
}
|
|
253
260
|
|
|
254
261
|
/**
|
|
@@ -268,6 +275,13 @@ export const UnifiedPayResultSchema = z.object({
|
|
|
268
275
|
requester: z.string().min(1),
|
|
269
276
|
deadline: z.string().min(1),
|
|
270
277
|
erc8004AgentId: z.string().optional(),
|
|
278
|
+
feeBreakdown: z.object({
|
|
279
|
+
grossAmount: z.string(),
|
|
280
|
+
providerNet: z.string(),
|
|
281
|
+
platformFee: z.string(),
|
|
282
|
+
feeBps: z.number(),
|
|
283
|
+
estimated: z.literal(true),
|
|
284
|
+
}).optional(),
|
|
271
285
|
});
|
|
272
286
|
|
|
273
287
|
// ============================================================================
|
package/src/types/x402.ts
CHANGED
|
@@ -194,6 +194,38 @@ export class X402Error extends Error {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
// ============================================================================
|
|
198
|
+
// Fee Types
|
|
199
|
+
// ============================================================================
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Fee breakdown for x402 payments routed through X402Relay.
|
|
203
|
+
*
|
|
204
|
+
* Shows how the gross amount was split between provider and platform.
|
|
205
|
+
* Fee = max(grossAmount * feeBps / 10000, MIN_FEE).
|
|
206
|
+
*
|
|
207
|
+
* NOTE: This is a client-side **estimate** computed from the configured
|
|
208
|
+
* platformFeeBps. The on-chain X402Relay contract is the source of truth.
|
|
209
|
+
* If an admin updates the relay's fee rate, this estimate may diverge
|
|
210
|
+
* from the actual on-chain split until the SDK config is refreshed.
|
|
211
|
+
*/
|
|
212
|
+
export interface X402FeeBreakdown {
|
|
213
|
+
/** Total amount from the 402 header (USDC wei, 6 decimals) */
|
|
214
|
+
grossAmount: string;
|
|
215
|
+
|
|
216
|
+
/** Estimated amount provider received: grossAmount - platformFee */
|
|
217
|
+
providerNet: string;
|
|
218
|
+
|
|
219
|
+
/** Estimated amount treasury received: max(feeBps%, $0.05) */
|
|
220
|
+
platformFee: string;
|
|
221
|
+
|
|
222
|
+
/** Fee rate used for estimate (basis points, e.g. 100 = 1%) */
|
|
223
|
+
feeBps: number;
|
|
224
|
+
|
|
225
|
+
/** True — this is a client-side estimate, not read from chain */
|
|
226
|
+
estimated: true;
|
|
227
|
+
}
|
|
228
|
+
|
|
197
229
|
// ============================================================================
|
|
198
230
|
// Type Guards
|
|
199
231
|
// ============================================================================
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* @module utils/ErrorRecoveryGuide
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { sdkLogger } from './Logger';
|
|
11
|
+
|
|
10
12
|
/**
|
|
11
13
|
* Error severity levels for prioritization
|
|
12
14
|
*/
|
|
@@ -650,14 +652,14 @@ export async function withRecoveryGuidance<T>(
|
|
|
650
652
|
}
|
|
651
653
|
|
|
652
654
|
if (logGuidance) {
|
|
653
|
-
|
|
655
|
+
sdkLogger.error(ErrorRecoveryGuide.formatGuidance(error));
|
|
654
656
|
}
|
|
655
657
|
|
|
656
658
|
if (autoRetry && recovery.retryable) {
|
|
657
659
|
const retryParams = ErrorRecoveryGuide.getRetryParams(error);
|
|
658
660
|
if (retryParams && attempts < retryParams.maxRetries) {
|
|
659
661
|
attempts++;
|
|
660
|
-
|
|
662
|
+
sdkLogger.info(
|
|
661
663
|
`Retrying (${attempts}/${retryParams.maxRetries}) after ${retryParams.delayMs}ms...`
|
|
662
664
|
);
|
|
663
665
|
await new Promise((resolve) =>
|
package/src/utils/IPFSClient.ts
CHANGED
|
@@ -74,8 +74,8 @@ export interface IPFSClientConfig {
|
|
|
74
74
|
allowedProtocols?: string[];
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
78
|
-
* Default:
|
|
77
|
+
* Allow localhost URLs (e.g., local IPFS daemon).
|
|
78
|
+
* Default: false (SSRF protection). Set to true explicitly for local development.
|
|
79
79
|
*/
|
|
80
80
|
allowLocalhost?: boolean;
|
|
81
81
|
}
|
|
@@ -85,7 +85,8 @@ export interface IPFSClientConfig {
|
|
|
85
85
|
*/
|
|
86
86
|
export const IPFS_CONFIGS = {
|
|
87
87
|
local: {
|
|
88
|
-
url: 'http://localhost:5001'
|
|
88
|
+
url: 'http://localhost:5001',
|
|
89
|
+
allowLocalhost: true, // Explicit opt-in for local development
|
|
89
90
|
},
|
|
90
91
|
infura: {
|
|
91
92
|
url: 'https://ipfs.infura.io:5001/api/v0'
|
|
@@ -128,14 +129,14 @@ export class IPFSHTTPClientImpl implements IPFSClient {
|
|
|
128
129
|
const url = config.url || 'http://localhost:5001';
|
|
129
130
|
|
|
130
131
|
// SECURITY FIX (MEDIUM-3): Validate URL
|
|
131
|
-
this.validateUrl(url, config.allowLocalhost ??
|
|
132
|
+
this.validateUrl(url, config.allowLocalhost ?? false, config.allowedProtocols);
|
|
132
133
|
|
|
133
134
|
this.config = {
|
|
134
135
|
url,
|
|
135
136
|
timeout: config.timeout || 60000,
|
|
136
137
|
maxSize: config.maxSize || IPFSHTTPClientImpl.DEFAULT_MAX_SIZE,
|
|
137
138
|
allowedProtocols: config.allowedProtocols || IPFSHTTPClientImpl.DEFAULT_ALLOWED_PROTOCOLS,
|
|
138
|
-
allowLocalhost: config.allowLocalhost ??
|
|
139
|
+
allowLocalhost: config.allowLocalhost ?? false,
|
|
139
140
|
auth: config.auth,
|
|
140
141
|
headers: config.headers,
|
|
141
142
|
} as Required<IPFSClientConfig>;
|
|
@@ -359,8 +360,9 @@ export function createIPFSClient(): IPFSClient {
|
|
|
359
360
|
});
|
|
360
361
|
}
|
|
361
362
|
|
|
362
|
-
// Default to local IPFS daemon
|
|
363
|
+
// Default to local IPFS daemon (explicit localhost opt-in)
|
|
363
364
|
return new IPFSHTTPClientImpl({
|
|
364
|
-
url: 'http://localhost:5001'
|
|
365
|
+
url: 'http://localhost:5001',
|
|
366
|
+
allowLocalhost: true,
|
|
365
367
|
});
|
|
366
368
|
}
|
|
@@ -44,7 +44,5 @@ if (require.main === module) {
|
|
|
44
44
|
console.log(typeHash);
|
|
45
45
|
console.log();
|
|
46
46
|
|
|
47
|
-
console.log('
|
|
48
|
-
console.log('- /Testnet/docs/AIP-4.md:204');
|
|
49
|
-
console.log('- /Testnet/docs/schemas/aip-4-delivery.eip712.json:11');
|
|
47
|
+
console.log('Use this type hash in your EIP-712 typed data configuration.');
|
|
50
48
|
}
|
package/src/utils/retry.ts
CHANGED
package/src/utils/validation.ts
CHANGED
|
@@ -320,7 +320,7 @@ export async function validateEndpointURL(endpoint: string, fieldName: string =
|
|
|
320
320
|
* @param fieldName - Field name for error messages
|
|
321
321
|
* @throws {InvalidCIDError} If CID is invalid
|
|
322
322
|
*/
|
|
323
|
-
export function validateCID(cid: string,
|
|
323
|
+
export function validateCID(cid: string, _fieldName: string = 'cid'): void {
|
|
324
324
|
if (!cid || typeof cid !== 'string') {
|
|
325
325
|
throw new InvalidCIDError(String(cid), 'CID is required');
|
|
326
326
|
}
|
|
@@ -337,7 +337,7 @@ export function validateCID(cid: string, fieldName: string = 'cid'): void {
|
|
|
337
337
|
* @param fieldName - Field name for error messages
|
|
338
338
|
* @throws {InvalidArweaveTxIdError} If TX ID is invalid
|
|
339
339
|
*/
|
|
340
|
-
export function validateArweaveTxId(txId: string,
|
|
340
|
+
export function validateArweaveTxId(txId: string, _fieldName: string = 'txId'): void {
|
|
341
341
|
if (!txId || typeof txId !== 'string') {
|
|
342
342
|
throw new InvalidArweaveTxIdError(String(txId), 'TX ID is required');
|
|
343
343
|
}
|