@agirails/sdk 2.5.2 → 2.5.4
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/dist/ACTPClient.d.ts +18 -0
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +67 -22
- package/dist/ACTPClient.js.map +1 -1
- package/dist/adapters/BasicAdapter.d.ts +12 -0
- package/dist/adapters/BasicAdapter.d.ts.map +1 -1
- package/dist/adapters/BasicAdapter.js +30 -4
- package/dist/adapters/BasicAdapter.js.map +1 -1
- package/dist/adapters/StandardAdapter.d.ts +20 -3
- package/dist/adapters/StandardAdapter.d.ts.map +1 -1
- package/dist/adapters/StandardAdapter.js +45 -11
- package/dist/adapters/StandardAdapter.js.map +1 -1
- package/dist/cli/commands/publish.js +16 -4
- package/dist/cli/commands/publish.js.map +1 -1
- package/dist/cli/commands/register.js +16 -4
- package/dist/cli/commands/register.js.map +1 -1
- package/dist/cli/commands/tx.js +31 -3
- package/dist/cli/commands/tx.js.map +1 -1
- package/dist/cli/utils/client.d.ts.map +1 -1
- package/dist/cli/utils/client.js +1 -0
- package/dist/cli/utils/client.js.map +1 -1
- package/dist/config/networks.d.ts +2 -2
- package/dist/config/networks.d.ts.map +1 -1
- package/dist/config/networks.js +27 -22
- package/dist/config/networks.js.map +1 -1
- package/dist/level0/request.d.ts.map +1 -1
- package/dist/level0/request.js +2 -1
- package/dist/level0/request.js.map +1 -1
- package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
- package/dist/runtime/BlockchainRuntime.js +11 -5
- package/dist/runtime/BlockchainRuntime.js.map +1 -1
- package/dist/runtime/MockStateManager.d.ts.map +1 -1
- package/dist/runtime/MockStateManager.js +2 -1
- package/dist/runtime/MockStateManager.js.map +1 -1
- package/dist/utils/IPFSClient.d.ts +3 -1
- package/dist/utils/IPFSClient.d.ts.map +1 -1
- package/dist/utils/IPFSClient.js +27 -7
- package/dist/utils/IPFSClient.js.map +1 -1
- package/dist/wallet/AutoWalletProvider.d.ts.map +1 -1
- package/dist/wallet/AutoWalletProvider.js +52 -18
- package/dist/wallet/AutoWalletProvider.js.map +1 -1
- package/dist/wallet/SmartWalletRouter.d.ts +116 -0
- package/dist/wallet/SmartWalletRouter.d.ts.map +1 -0
- package/dist/wallet/SmartWalletRouter.js +212 -0
- package/dist/wallet/SmartWalletRouter.js.map +1 -0
- package/dist/wallet/aa/DualNonceManager.d.ts +19 -0
- package/dist/wallet/aa/DualNonceManager.d.ts.map +1 -1
- package/dist/wallet/aa/DualNonceManager.js +100 -5
- package/dist/wallet/aa/DualNonceManager.js.map +1 -1
- package/package.json +3 -6
- package/src/ACTPClient.ts +0 -1579
- package/src/abi/ACTPKernel.json +0 -1356
- package/src/abi/AgentRegistry.json +0 -915
- package/src/abi/ERC20.json +0 -40
- package/src/abi/EscrowVault.json +0 -134
- package/src/abi/IdentityRegistry.json +0 -316
- package/src/adapters/AdapterRegistry.ts +0 -173
- package/src/adapters/AdapterRouter.ts +0 -416
- package/src/adapters/BaseAdapter.ts +0 -498
- package/src/adapters/BasicAdapter.ts +0 -514
- package/src/adapters/IAdapter.ts +0 -292
- package/src/adapters/StandardAdapter.ts +0 -555
- package/src/adapters/X402Adapter.ts +0 -731
- package/src/adapters/index.ts +0 -60
- package/src/builders/DeliveryProofBuilder.ts +0 -327
- package/src/builders/QuoteBuilder.ts +0 -483
- package/src/builders/index.ts +0 -17
- package/src/cli/commands/balance.ts +0 -110
- package/src/cli/commands/batch.ts +0 -487
- package/src/cli/commands/config.ts +0 -231
- package/src/cli/commands/deploy-check.ts +0 -364
- package/src/cli/commands/deploy-env.ts +0 -120
- package/src/cli/commands/diff.ts +0 -141
- package/src/cli/commands/init.ts +0 -469
- package/src/cli/commands/mint.ts +0 -116
- package/src/cli/commands/pay.ts +0 -113
- package/src/cli/commands/publish.ts +0 -475
- package/src/cli/commands/pull.ts +0 -124
- package/src/cli/commands/register.ts +0 -247
- package/src/cli/commands/simulate.ts +0 -345
- package/src/cli/commands/time.ts +0 -302
- package/src/cli/commands/tx.ts +0 -448
- package/src/cli/commands/watch.ts +0 -211
- package/src/cli/index.ts +0 -134
- package/src/cli/utils/client.ts +0 -251
- package/src/cli/utils/config.ts +0 -389
- package/src/cli/utils/output.ts +0 -465
- package/src/cli/utils/wallet.ts +0 -109
- package/src/config/agirailsmd.ts +0 -262
- package/src/config/networks.ts +0 -275
- package/src/config/pendingPublish.ts +0 -237
- package/src/config/publishPipeline.ts +0 -359
- package/src/config/syncOperations.ts +0 -279
- package/src/erc8004/ERC8004Bridge.ts +0 -462
- package/src/erc8004/ReputationReporter.ts +0 -468
- package/src/erc8004/index.ts +0 -61
- package/src/errors/index.ts +0 -427
- package/src/index.ts +0 -364
- package/src/level0/Provider.ts +0 -117
- package/src/level0/ServiceDirectory.ts +0 -131
- package/src/level0/index.ts +0 -10
- package/src/level0/provide.ts +0 -132
- package/src/level0/request.ts +0 -432
- package/src/level1/Agent.ts +0 -1426
- package/src/level1/index.ts +0 -10
- package/src/level1/pricing/PriceCalculator.ts +0 -255
- package/src/level1/pricing/PricingStrategy.ts +0 -198
- package/src/level1/types/Job.ts +0 -179
- package/src/level1/types/Options.ts +0 -291
- package/src/level1/types/index.ts +0 -8
- package/src/protocol/ACTPKernel.ts +0 -808
- package/src/protocol/AgentRegistry.ts +0 -559
- package/src/protocol/DIDManager.ts +0 -629
- package/src/protocol/DIDResolver.ts +0 -554
- package/src/protocol/EASHelper.ts +0 -378
- package/src/protocol/EscrowVault.ts +0 -255
- package/src/protocol/EventMonitor.ts +0 -204
- package/src/protocol/MessageSigner.ts +0 -510
- package/src/protocol/ProofGenerator.ts +0 -339
- package/src/protocol/QuoteBuilder.ts +0 -15
- package/src/registry/AgentRegistryClient.ts +0 -202
- package/src/runtime/BlockchainRuntime.ts +0 -1015
- package/src/runtime/IACTPRuntime.ts +0 -306
- package/src/runtime/MockRuntime.ts +0 -1298
- package/src/runtime/MockStateManager.ts +0 -576
- package/src/runtime/index.ts +0 -25
- package/src/runtime/types/MockState.ts +0 -237
- package/src/storage/ArchiveBundleBuilder.ts +0 -561
- package/src/storage/ArweaveClient.ts +0 -946
- package/src/storage/FilebaseClient.ts +0 -790
- package/src/storage/index.ts +0 -96
- package/src/storage/types.ts +0 -348
- package/src/types/adapter.ts +0 -310
- package/src/types/agent.ts +0 -79
- package/src/types/did.ts +0 -223
- package/src/types/eip712.ts +0 -175
- package/src/types/erc8004.ts +0 -293
- package/src/types/escrow.ts +0 -27
- package/src/types/index.ts +0 -17
- package/src/types/message.ts +0 -145
- package/src/types/state.ts +0 -87
- package/src/types/transaction.ts +0 -69
- package/src/types/x402.ts +0 -251
- package/src/utils/ErrorRecoveryGuide.ts +0 -676
- package/src/utils/Helpers.ts +0 -688
- package/src/utils/IPFSClient.ts +0 -368
- package/src/utils/Logger.ts +0 -484
- package/src/utils/NonceManager.ts +0 -591
- package/src/utils/RateLimiter.ts +0 -534
- package/src/utils/ReceivedNonceTracker.ts +0 -567
- package/src/utils/SDKLifecycle.ts +0 -416
- package/src/utils/SecureNonce.ts +0 -78
- package/src/utils/Semaphore.ts +0 -276
- package/src/utils/UsedAttestationTracker.ts +0 -385
- package/src/utils/canonicalJson.ts +0 -38
- package/src/utils/circuitBreaker.ts +0 -324
- package/src/utils/computeTypeHash.ts +0 -48
- package/src/utils/fsSafe.ts +0 -80
- package/src/utils/index.ts +0 -80
- package/src/utils/retry.ts +0 -364
- package/src/utils/security.ts +0 -418
- package/src/utils/validation.ts +0 -540
- package/src/wallet/AutoWalletProvider.ts +0 -299
- package/src/wallet/EOAWalletProvider.ts +0 -69
- package/src/wallet/IWalletProvider.ts +0 -135
- package/src/wallet/aa/BundlerClient.ts +0 -274
- package/src/wallet/aa/DualNonceManager.ts +0 -173
- package/src/wallet/aa/PaymasterClient.ts +0 -174
- package/src/wallet/aa/TransactionBatcher.ts +0 -353
- package/src/wallet/aa/UserOpBuilder.ts +0 -246
- package/src/wallet/aa/constants.ts +0 -60
- package/src/wallet/keystore.ts +0 -240
package/src/utils/IPFSClient.ts
DELETED
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IPFS Client Implementation
|
|
3
|
-
* Wrapper around kubo-rpc-client (formerly ipfs-http-client) for AIP-4 delivery proof uploads
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { create, IPFSHTTPClient, Options } from 'kubo-rpc-client';
|
|
7
|
-
import { sdkLogger } from './Logger';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* IPFS Client Interface (from DeliveryProofBuilder)
|
|
11
|
-
*/
|
|
12
|
-
export interface IPFSClient {
|
|
13
|
-
/**
|
|
14
|
-
* Upload data to IPFS
|
|
15
|
-
* @param data - JSON string or buffer
|
|
16
|
-
* @returns CIDv1 string (base32, e.g., "bafybeig...")
|
|
17
|
-
*/
|
|
18
|
-
add(data: string | Buffer): Promise<string>;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Pin content to prevent garbage collection
|
|
22
|
-
* @param cid - IPFS CID
|
|
23
|
-
*/
|
|
24
|
-
pin(cid: string): Promise<void>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Retrieve content from IPFS
|
|
28
|
-
* @param cid - IPFS CID
|
|
29
|
-
* @returns Content as string
|
|
30
|
-
*/
|
|
31
|
-
get(cid: string): Promise<string>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* IPFS Client Configuration
|
|
36
|
-
*/
|
|
37
|
-
export interface IPFSClientConfig {
|
|
38
|
-
/**
|
|
39
|
-
* IPFS HTTP API endpoint
|
|
40
|
-
* Default: http://localhost:5001 (local IPFS daemon)
|
|
41
|
-
* Production: https://ipfs.infura.io:5001/api/v0 (Infura)
|
|
42
|
-
*/
|
|
43
|
-
url?: string;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* API authentication (for Infura, Pinata, etc.)
|
|
47
|
-
*/
|
|
48
|
-
auth?: {
|
|
49
|
-
username: string;
|
|
50
|
-
password: string;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* HTTP headers (for API keys)
|
|
55
|
-
*/
|
|
56
|
-
headers?: Record<string, string>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Request timeout (ms)
|
|
60
|
-
* Default: 60000 (60 seconds)
|
|
61
|
-
*/
|
|
62
|
-
timeout?: number;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* SECURITY FIX (MEDIUM-3): Maximum content size in bytes
|
|
66
|
-
* Default: 50MB (50 * 1024 * 1024)
|
|
67
|
-
*/
|
|
68
|
-
maxSize?: number;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* SECURITY FIX (MEDIUM-3): Allowed URL protocols
|
|
72
|
-
* Default: ['http:', 'https:'] (http for localhost, https for remote)
|
|
73
|
-
*/
|
|
74
|
-
allowedProtocols?: string[];
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Allow localhost URLs (e.g., local IPFS daemon).
|
|
78
|
-
* Default: false (SSRF protection). Set to true explicitly for local development.
|
|
79
|
-
*/
|
|
80
|
-
allowLocalhost?: boolean;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Default IPFS configurations
|
|
85
|
-
*/
|
|
86
|
-
export const IPFS_CONFIGS = {
|
|
87
|
-
local: {
|
|
88
|
-
url: 'http://localhost:5001',
|
|
89
|
-
allowLocalhost: true, // Explicit opt-in for local development
|
|
90
|
-
},
|
|
91
|
-
infura: {
|
|
92
|
-
url: 'https://ipfs.infura.io:5001/api/v0'
|
|
93
|
-
// Auth required: Set INFURA_PROJECT_ID and INFURA_PROJECT_SECRET
|
|
94
|
-
},
|
|
95
|
-
pinata: {
|
|
96
|
-
url: 'https://api.pinata.cloud'
|
|
97
|
-
// Headers required: Set pinata_api_key and pinata_secret_api_key
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* IPFS HTTP Client Implementation
|
|
103
|
-
* Uses ipfs-http-client library
|
|
104
|
-
*
|
|
105
|
-
* SECURITY FIX (MEDIUM-3): Now includes URL and size validation
|
|
106
|
-
*/
|
|
107
|
-
export class IPFSHTTPClientImpl implements IPFSClient {
|
|
108
|
-
private client: IPFSHTTPClient;
|
|
109
|
-
private config: Required<IPFSClientConfig>;
|
|
110
|
-
|
|
111
|
-
// SECURITY FIX (MEDIUM-3): Default security settings
|
|
112
|
-
private static readonly DEFAULT_MAX_SIZE = 50 * 1024 * 1024; // 50MB
|
|
113
|
-
private static readonly DEFAULT_ALLOWED_PROTOCOLS = ['http:', 'https:'];
|
|
114
|
-
private static readonly BLOCKED_HOSTS = [
|
|
115
|
-
'metadata.google.internal',
|
|
116
|
-
'169.254.169.254',
|
|
117
|
-
'metadata.aws.internal',
|
|
118
|
-
];
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Create IPFS client
|
|
122
|
-
*
|
|
123
|
-
* SECURITY FIX (MEDIUM-3): Validates URL and adds size limits
|
|
124
|
-
*
|
|
125
|
-
* @param config - IPFS client configuration
|
|
126
|
-
* @throws Error if URL is invalid or blocked
|
|
127
|
-
*/
|
|
128
|
-
constructor(config: IPFSClientConfig = {}) {
|
|
129
|
-
const url = config.url || 'http://localhost:5001';
|
|
130
|
-
|
|
131
|
-
// SECURITY FIX (MEDIUM-3): Validate URL
|
|
132
|
-
this.validateUrl(url, config.allowLocalhost ?? false, config.allowedProtocols);
|
|
133
|
-
|
|
134
|
-
this.config = {
|
|
135
|
-
url,
|
|
136
|
-
timeout: config.timeout || 60000,
|
|
137
|
-
maxSize: config.maxSize || IPFSHTTPClientImpl.DEFAULT_MAX_SIZE,
|
|
138
|
-
allowedProtocols: config.allowedProtocols || IPFSHTTPClientImpl.DEFAULT_ALLOWED_PROTOCOLS,
|
|
139
|
-
allowLocalhost: config.allowLocalhost ?? false,
|
|
140
|
-
auth: config.auth,
|
|
141
|
-
headers: config.headers,
|
|
142
|
-
} as Required<IPFSClientConfig>;
|
|
143
|
-
|
|
144
|
-
const options: Options = {
|
|
145
|
-
url: this.config.url,
|
|
146
|
-
timeout: this.config.timeout
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// Add authentication if provided
|
|
150
|
-
if (this.config.auth) {
|
|
151
|
-
options.headers = {
|
|
152
|
-
...this.config.headers,
|
|
153
|
-
authorization: 'Basic ' + Buffer.from(
|
|
154
|
-
`${this.config.auth.username}:${this.config.auth.password}`
|
|
155
|
-
).toString('base64')
|
|
156
|
-
};
|
|
157
|
-
} else if (this.config.headers) {
|
|
158
|
-
options.headers = this.config.headers;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
this.client = create(options);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* SECURITY FIX (MEDIUM-3): Validate IPFS endpoint URL
|
|
166
|
-
*/
|
|
167
|
-
private validateUrl(
|
|
168
|
-
url: string,
|
|
169
|
-
allowLocalhost: boolean,
|
|
170
|
-
allowedProtocols?: string[]
|
|
171
|
-
): void {
|
|
172
|
-
let parsed: URL;
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
parsed = new URL(url);
|
|
176
|
-
} catch {
|
|
177
|
-
throw new Error(`Invalid IPFS endpoint URL: ${url}`);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const protocols = allowedProtocols || IPFSHTTPClientImpl.DEFAULT_ALLOWED_PROTOCOLS;
|
|
181
|
-
if (!protocols.includes(parsed.protocol)) {
|
|
182
|
-
throw new Error(
|
|
183
|
-
`IPFS endpoint protocol "${parsed.protocol}" not allowed. ` +
|
|
184
|
-
`Allowed protocols: ${protocols.join(', ')}`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
189
|
-
|
|
190
|
-
// Check blocked hosts (cloud metadata endpoints)
|
|
191
|
-
if (IPFSHTTPClientImpl.BLOCKED_HOSTS.includes(hostname)) {
|
|
192
|
-
throw new Error(
|
|
193
|
-
`IPFS endpoint hostname "${hostname}" is blocked for security reasons.`
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Check localhost
|
|
198
|
-
const isLocalhost = ['localhost', '127.0.0.1', '0.0.0.0', '[::1]'].includes(hostname);
|
|
199
|
-
if (isLocalhost && !allowLocalhost) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`Localhost IPFS endpoints are disabled. Set allowLocalhost: true to enable.`
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// For remote hosts, require HTTPS
|
|
206
|
-
if (!isLocalhost && parsed.protocol !== 'https:') {
|
|
207
|
-
sdkLogger.warn('Using non-HTTPS protocol for remote IPFS endpoint - data may be exposed in transit', {
|
|
208
|
-
protocol: parsed.protocol,
|
|
209
|
-
hostname,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Upload data to IPFS
|
|
216
|
-
*
|
|
217
|
-
* SECURITY FIX (MEDIUM-3): Validates size before upload
|
|
218
|
-
*
|
|
219
|
-
* @param data - JSON string or buffer
|
|
220
|
-
* @returns CIDv1 string (base32)
|
|
221
|
-
* @throws Error if data exceeds maxSize
|
|
222
|
-
*/
|
|
223
|
-
async add(data: string | Buffer): Promise<string> {
|
|
224
|
-
try {
|
|
225
|
-
const content = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;
|
|
226
|
-
|
|
227
|
-
// SECURITY FIX (MEDIUM-3): Check size before upload
|
|
228
|
-
if (content.length > this.config.maxSize) {
|
|
229
|
-
throw new Error(
|
|
230
|
-
`Content too large: ${content.length} bytes exceeds maximum of ${this.config.maxSize} bytes`
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const result = await this.client.add(content, {
|
|
235
|
-
cidVersion: 1, // Use CIDv1 (base32)
|
|
236
|
-
hashAlg: 'sha2-256',
|
|
237
|
-
pin: true // Auto-pin on upload
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// Convert CID to base32 string (e.g., "bafybeig...")
|
|
241
|
-
return result.cid.toString();
|
|
242
|
-
} catch (error) {
|
|
243
|
-
throw new Error(`IPFS upload failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Pin content to prevent garbage collection
|
|
249
|
-
* @param cid - IPFS CID
|
|
250
|
-
*/
|
|
251
|
-
async pin(cid: string): Promise<void> {
|
|
252
|
-
try {
|
|
253
|
-
await this.client.pin.add(cid);
|
|
254
|
-
} catch (error) {
|
|
255
|
-
throw new Error(`IPFS pin failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Retrieve content from IPFS
|
|
261
|
-
*
|
|
262
|
-
* SECURITY FIX (MEDIUM-3): Validates size during retrieval
|
|
263
|
-
*
|
|
264
|
-
* @param cid - IPFS CID
|
|
265
|
-
* @returns Content as string
|
|
266
|
-
* @throws Error if content exceeds maxSize
|
|
267
|
-
*/
|
|
268
|
-
async get(cid: string): Promise<string> {
|
|
269
|
-
try {
|
|
270
|
-
const chunks: Uint8Array[] = [];
|
|
271
|
-
let totalLength = 0;
|
|
272
|
-
|
|
273
|
-
for await (const chunk of this.client.cat(cid)) {
|
|
274
|
-
totalLength += chunk.length;
|
|
275
|
-
|
|
276
|
-
// SECURITY FIX (MEDIUM-3): Check size during streaming to prevent DoS
|
|
277
|
-
if (totalLength > this.config.maxSize) {
|
|
278
|
-
throw new Error(
|
|
279
|
-
`Content too large: ${totalLength}+ bytes exceeds maximum of ${this.config.maxSize} bytes. ` +
|
|
280
|
-
`Consider increasing maxSize in IPFSClientConfig if this is expected.`
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
chunks.push(chunk);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Concatenate all chunks
|
|
288
|
-
const result = new Uint8Array(totalLength);
|
|
289
|
-
let offset = 0;
|
|
290
|
-
|
|
291
|
-
for (const chunk of chunks) {
|
|
292
|
-
result.set(chunk, offset);
|
|
293
|
-
offset += chunk.length;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return Buffer.from(result).toString('utf-8');
|
|
297
|
-
} catch (error) {
|
|
298
|
-
throw new Error(`IPFS retrieval failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Check if IPFS daemon is reachable
|
|
304
|
-
* @returns true if connected, false otherwise
|
|
305
|
-
*/
|
|
306
|
-
async isOnline(): Promise<boolean> {
|
|
307
|
-
try {
|
|
308
|
-
await this.client.id();
|
|
309
|
-
return true;
|
|
310
|
-
} catch {
|
|
311
|
-
return false;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Get IPFS node ID
|
|
317
|
-
* @returns IPFS node ID
|
|
318
|
-
*/
|
|
319
|
-
async getNodeId(): Promise<string> {
|
|
320
|
-
try {
|
|
321
|
-
const id = await this.client.id();
|
|
322
|
-
return id.id.toString();
|
|
323
|
-
} catch (error) {
|
|
324
|
-
throw new Error(`Failed to get node ID: ${error instanceof Error ? error.message : String(error)}`);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Create IPFS client with environment-based configuration
|
|
331
|
-
* Checks for IPFS_URL, INFURA_PROJECT_ID, PINATA_API_KEY env vars
|
|
332
|
-
*/
|
|
333
|
-
export function createIPFSClient(): IPFSClient {
|
|
334
|
-
// Check for Infura credentials
|
|
335
|
-
if (process.env.INFURA_PROJECT_ID && process.env.INFURA_PROJECT_SECRET) {
|
|
336
|
-
return new IPFSHTTPClientImpl({
|
|
337
|
-
url: 'https://ipfs.infura.io:5001/api/v0',
|
|
338
|
-
auth: {
|
|
339
|
-
username: process.env.INFURA_PROJECT_ID,
|
|
340
|
-
password: process.env.INFURA_PROJECT_SECRET
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Check for Pinata credentials
|
|
346
|
-
if (process.env.PINATA_API_KEY && process.env.PINATA_SECRET_API_KEY) {
|
|
347
|
-
return new IPFSHTTPClientImpl({
|
|
348
|
-
url: 'https://api.pinata.cloud',
|
|
349
|
-
headers: {
|
|
350
|
-
pinata_api_key: process.env.PINATA_API_KEY,
|
|
351
|
-
pinata_secret_api_key: process.env.PINATA_SECRET_API_KEY
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Check for custom IPFS URL
|
|
357
|
-
if (process.env.IPFS_URL) {
|
|
358
|
-
return new IPFSHTTPClientImpl({
|
|
359
|
-
url: process.env.IPFS_URL
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Default to local IPFS daemon (explicit localhost opt-in)
|
|
364
|
-
return new IPFSHTTPClientImpl({
|
|
365
|
-
url: 'http://localhost:5001',
|
|
366
|
-
allowLocalhost: true,
|
|
367
|
-
});
|
|
368
|
-
}
|