@agirails/sdk 2.3.0 → 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 +45 -8
- package/dist/ACTPClient.d.ts +35 -1
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +156 -26
- package/dist/ACTPClient.js.map +1 -1
- 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/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +210 -18
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/publish.d.ts.map +1 -1
- package/dist/cli/commands/publish.js.map +1 -1
- 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 +3 -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/networks.d.ts +20 -4
- package/dist/config/networks.d.ts.map +1 -1
- package/dist/config/networks.js +59 -27
- package/dist/config/networks.js.map +1 -1
- package/dist/config/publishPipeline.d.ts +14 -0
- package/dist/config/publishPipeline.d.ts.map +1 -1
- package/dist/config/publishPipeline.js +2 -1
- package/dist/config/publishPipeline.js.map +1 -1
- 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 +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/level1/Agent.js +4 -4
- 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/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/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/package.json +4 -2
- package/src/ACTPClient.ts +217 -31
- package/src/adapters/AdapterRouter.ts +0 -1
- package/src/adapters/BasicAdapter.ts +41 -1
- package/src/cli/commands/init.ts +247 -19
- package/src/cli/commands/publish.ts +1 -2
- package/src/cli/commands/register.ts +233 -0
- package/src/cli/index.ts +4 -0
- package/src/cli/utils/config.ts +9 -0
- package/src/config/networks.ts +82 -27
- package/src/config/publishPipeline.ts +2 -2
- package/src/erc8004/ERC8004Bridge.ts +6 -5
- package/src/erc8004/ReputationReporter.ts +14 -18
- package/src/index.ts +12 -0
- package/src/level1/Agent.ts +5 -5
- package/src/protocol/ACTPKernel.ts +20 -10
- package/src/protocol/EventMonitor.ts +14 -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/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/config/networks.ts
CHANGED
|
@@ -15,6 +15,16 @@ import { ethers } from 'ethers';
|
|
|
15
15
|
const BASE_SEPOLIA_RPC_URL = process.env.BASE_SEPOLIA_RPC || 'https://sepolia.base.org';
|
|
16
16
|
const BASE_MAINNET_RPC_URL = process.env.BASE_MAINNET_RPC || 'https://mainnet.base.org';
|
|
17
17
|
|
|
18
|
+
// AGIRAILS CDP Client API Key — safe to embed, cannot access funds/portfolios.
|
|
19
|
+
// Developers can override with their own key via CDP_API_KEY env var.
|
|
20
|
+
// Paymaster policy restricts sponsorship to AGIRAILS contracts only.
|
|
21
|
+
const CDP_CLIENT_KEY = process.env.CDP_API_KEY || '2txciN85t41erCjveqgNnXYyHRcoo5xP';
|
|
22
|
+
|
|
23
|
+
// Pimlico failover — bundler/paymaster backup if Coinbase CDP is down.
|
|
24
|
+
// Safe to embed: restricted by contract allowlist (AGIRAILS contracts only).
|
|
25
|
+
// Developers can override with their own key via PIMLICO_API_KEY env var.
|
|
26
|
+
const PIMLICO_KEY = process.env.PIMLICO_API_KEY || 'pim_YiHmeAijzTPUvo1UMmXUiN';
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* Network configuration
|
|
20
30
|
*/
|
|
@@ -49,6 +59,27 @@ export interface NetworkConfig {
|
|
|
49
59
|
* Set to undefined for no limit (testnet only).
|
|
50
60
|
*/
|
|
51
61
|
maxTransactionAmount?: number;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* AIP-12: Account Abstraction (AA) configuration.
|
|
65
|
+
* EntryPoint v0.6 + CoinbaseSmartWallet.
|
|
66
|
+
*/
|
|
67
|
+
aa?: {
|
|
68
|
+
/** ERC-4337 EntryPoint v0.6 address */
|
|
69
|
+
entryPoint: string;
|
|
70
|
+
/** CoinbaseSmartWallet factory address */
|
|
71
|
+
smartWalletFactory: string;
|
|
72
|
+
/** Bundler RPC URLs */
|
|
73
|
+
bundlerUrls: {
|
|
74
|
+
coinbase: string;
|
|
75
|
+
pimlico?: string;
|
|
76
|
+
};
|
|
77
|
+
/** Paymaster RPC URLs (ERC-7677) */
|
|
78
|
+
paymasterUrls: {
|
|
79
|
+
coinbase: string;
|
|
80
|
+
pimlico?: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
52
83
|
}
|
|
53
84
|
|
|
54
85
|
/**
|
|
@@ -60,38 +91,44 @@ export const BASE_SEPOLIA: NetworkConfig = {
|
|
|
60
91
|
rpcUrl: BASE_SEPOLIA_RPC_URL,
|
|
61
92
|
blockExplorer: 'https://sepolia.basescan.org',
|
|
62
93
|
contracts: {
|
|
63
|
-
// Redeployed 2026-02-06 with agentId support
|
|
64
94
|
actpKernel: '0x469CBADbACFFE096270594F0a31f0EEC53753411',
|
|
65
95
|
escrowVault: '0x57f888261b629bB380dfb983f5DA6c70Ff2D49E5',
|
|
66
96
|
usdc: '0x444b4e1A65949AB2ac75979D5d0166Eb7A248Ccb', // MockUSDC
|
|
67
|
-
// EAS contracts (Base native deployment)
|
|
68
97
|
eas: '0x4200000000000000000000000000000000000021',
|
|
69
98
|
easSchemaRegistry: '0x4200000000000000000000000000000000000020',
|
|
70
|
-
|
|
71
|
-
agentRegistry: '0xFed6914Aa70c0a53E9c7Cc4d2Ae159e4748fb09D',
|
|
72
|
-
// AIP-7 Identity Registry - ERC-1056 DID Registry (deployed 2026-01-09)
|
|
99
|
+
agentRegistry: '0xDd6D66924B43419F484aE981F174b803487AF25A',
|
|
73
100
|
identityRegistry: '0xF64F748C7802a68Cb936a9213881fE74e83FDA97',
|
|
74
|
-
// AIP-7 Archive Treasury - Arweave funding (deployed 2026-01-09)
|
|
75
101
|
archiveTreasury: '0xeB75DE7cF5ce77ab15BB0fFa3a2A79e6aaa554B0',
|
|
76
|
-
|
|
77
|
-
// x402Relay: '0x...',
|
|
102
|
+
x402Relay: '0x4DCD02b276Dbeab57c265B72435e90507b6Ac81A',
|
|
78
103
|
},
|
|
79
104
|
eas: {
|
|
80
|
-
// Deployed 2025-11-23 - AIP-4 delivery proof schema
|
|
81
105
|
deliverySchemaUID: '0x1b0ebdf0bd20c28ec9d5362571ce8715a55f46e81c3de2f9b0d8e1b95fb5ffce'
|
|
82
106
|
},
|
|
83
107
|
gasSettings: {
|
|
84
108
|
maxFeePerGas: ethers.parseUnits('2', 'gwei'),
|
|
85
109
|
maxPriorityFeePerGas: ethers.parseUnits('1', 'gwei')
|
|
86
|
-
}
|
|
110
|
+
},
|
|
111
|
+
// AIP-12: Account Abstraction
|
|
112
|
+
aa: {
|
|
113
|
+
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
|
|
114
|
+
smartWalletFactory: '0xBA5ED110eFDBa3D005bfC882d75358ACBbB85842',
|
|
115
|
+
bundlerUrls: {
|
|
116
|
+
// Coinbase CDP bundler — set CDP_API_KEY env var
|
|
117
|
+
coinbase: process.env.CDP_BUNDLER_URL || `https://api.developer.coinbase.com/rpc/v1/base-sepolia/${CDP_CLIENT_KEY}`,
|
|
118
|
+
// Pimlico backup bundler — set PIMLICO_API_KEY env var
|
|
119
|
+
pimlico: process.env.PIMLICO_BUNDLER_URL || `https://api.pimlico.io/v2/84532/rpc?apikey=${PIMLICO_KEY}`,
|
|
120
|
+
},
|
|
121
|
+
paymasterUrls: {
|
|
122
|
+
// Coinbase CDP paymaster — same endpoint as bundler
|
|
123
|
+
coinbase: process.env.CDP_PAYMASTER_URL || `https://api.developer.coinbase.com/rpc/v1/base-sepolia/${CDP_CLIENT_KEY}`,
|
|
124
|
+
// Pimlico failover paymaster
|
|
125
|
+
pimlico: process.env.PIMLICO_PAYMASTER_URL || `https://api.pimlico.io/v2/84532/rpc?apikey=${PIMLICO_KEY}`,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
87
128
|
};
|
|
88
129
|
|
|
89
130
|
/**
|
|
90
131
|
* Base Mainnet Configuration
|
|
91
|
-
*
|
|
92
|
-
* WARNING: Mainnet contracts are NOT YET DEPLOYED.
|
|
93
|
-
* Using 'base-mainnet' will throw an error until contracts are deployed.
|
|
94
|
-
* Use 'base-sepolia' for testnet development.
|
|
95
132
|
*/
|
|
96
133
|
export const BASE_MAINNET: NetworkConfig = {
|
|
97
134
|
name: 'Base Mainnet',
|
|
@@ -99,21 +136,16 @@ export const BASE_MAINNET: NetworkConfig = {
|
|
|
99
136
|
rpcUrl: BASE_MAINNET_RPC_URL,
|
|
100
137
|
blockExplorer: 'https://basescan.org',
|
|
101
138
|
contracts: {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // Official USDC on Base
|
|
106
|
-
// EAS contracts (Base native deployment)
|
|
139
|
+
actpKernel: '0x132B9eB321dBB57c828B083844287171BDC92d29',
|
|
140
|
+
escrowVault: '0x6aAF45882c4b0dD34130ecC790bb5Ec6be7fFb99',
|
|
141
|
+
usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
107
142
|
eas: '0x4200000000000000000000000000000000000021',
|
|
108
143
|
easSchemaRegistry: '0x4200000000000000000000000000000000000020',
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// X402Relay - atomic payment fee splitting (TODO: deploy and set address)
|
|
113
|
-
// x402Relay: '0x...',
|
|
144
|
+
agentRegistry: '0x6fB222CF3DDdf37Bcb248EE7BBBA42Fb41901de8',
|
|
145
|
+
archiveTreasury: '0x0516C411C0E8d75D17A768022819a0a4FB3cA2f2',
|
|
146
|
+
x402Relay: '0x81DFb954A3D58FEc24Fc9c946aC2C71a911609F8',
|
|
114
147
|
},
|
|
115
148
|
eas: {
|
|
116
|
-
// Registered 2026-02-03
|
|
117
149
|
deliverySchemaUID: '0x166501e7476e2fcf9214c4c5144533c2957d56fe59d639effc1719a0658d9c9a'
|
|
118
150
|
},
|
|
119
151
|
gasSettings: {
|
|
@@ -125,7 +157,22 @@ export const BASE_MAINNET: NetworkConfig = {
|
|
|
125
157
|
* This limits exposure in case of undiscovered vulnerabilities.
|
|
126
158
|
* Will be removed/increased after formal security audit.
|
|
127
159
|
*/
|
|
128
|
-
maxTransactionAmount: 1000
|
|
160
|
+
maxTransactionAmount: 1000,
|
|
161
|
+
// AIP-12: Account Abstraction
|
|
162
|
+
aa: {
|
|
163
|
+
entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
|
|
164
|
+
smartWalletFactory: '0xBA5ED110eFDBa3D005bfC882d75358ACBbB85842',
|
|
165
|
+
bundlerUrls: {
|
|
166
|
+
coinbase: process.env.CDP_BUNDLER_URL || `https://api.developer.coinbase.com/rpc/v1/base/${CDP_CLIENT_KEY}`,
|
|
167
|
+
// Pimlico backup bundler — set PIMLICO_API_KEY env var
|
|
168
|
+
pimlico: process.env.PIMLICO_BUNDLER_URL || `https://api.pimlico.io/v2/8453/rpc?apikey=${PIMLICO_KEY}`,
|
|
169
|
+
},
|
|
170
|
+
paymasterUrls: {
|
|
171
|
+
coinbase: process.env.CDP_PAYMASTER_URL || `https://api.developer.coinbase.com/rpc/v1/base/${CDP_CLIENT_KEY}`,
|
|
172
|
+
// Pimlico failover paymaster
|
|
173
|
+
pimlico: process.env.PIMLICO_PAYMASTER_URL || `https://api.pimlico.io/v2/8453/rpc?apikey=${PIMLICO_KEY}`,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
129
176
|
};
|
|
130
177
|
|
|
131
178
|
/**
|
|
@@ -174,7 +221,15 @@ export function getNetwork(network: string): NetworkConfig {
|
|
|
174
221
|
gasSettings: {
|
|
175
222
|
maxFeePerGas: config.gasSettings.maxFeePerGas,
|
|
176
223
|
maxPriorityFeePerGas: config.gasSettings.maxPriorityFeePerGas
|
|
177
|
-
}
|
|
224
|
+
},
|
|
225
|
+
...(config.aa ? {
|
|
226
|
+
aa: {
|
|
227
|
+
entryPoint: config.aa.entryPoint,
|
|
228
|
+
smartWalletFactory: config.aa.smartWalletFactory,
|
|
229
|
+
bundlerUrls: { ...config.aa.bundlerUrls },
|
|
230
|
+
paymasterUrls: { ...config.aa.paymasterUrls },
|
|
231
|
+
}
|
|
232
|
+
} : {}),
|
|
178
233
|
};
|
|
179
234
|
}
|
|
180
235
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { readFileSync, writeFileSync } from 'fs';
|
|
15
15
|
import { Signer, keccak256, toUtf8Bytes } from 'ethers';
|
|
16
|
-
import { parseAgirailsMd, computeConfigHash,
|
|
16
|
+
import { parseAgirailsMd, computeConfigHash, serializeAgirailsMd } from './agirailsmd';
|
|
17
17
|
import { AgentRegistryClient } from '../registry/AgentRegistryClient';
|
|
18
18
|
import { AgentRegistry } from '../protocol/AgentRegistry';
|
|
19
19
|
import { FilebaseClient } from '../storage/FilebaseClient';
|
|
@@ -110,7 +110,7 @@ function usdcToBaseUnits(value: number, fieldName: string): bigint {
|
|
|
110
110
|
*
|
|
111
111
|
* @throws Error if neither services nor capabilities are present
|
|
112
112
|
*/
|
|
113
|
-
function extractRegistrationParams(
|
|
113
|
+
export function extractRegistrationParams(
|
|
114
114
|
frontmatter: Record<string, unknown>
|
|
115
115
|
): { endpoint: string; serviceDescriptors: ServiceDescriptor[] } {
|
|
116
116
|
// Endpoint: use frontmatter field or placeholder
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
ERC8004_IDENTITY_ABI,
|
|
39
39
|
ERC8004_DEFAULT_RPC,
|
|
40
40
|
} from '../types/erc8004';
|
|
41
|
+
import { sdkLogger } from '../utils/Logger';
|
|
41
42
|
|
|
42
43
|
// ============================================================================
|
|
43
44
|
// Types
|
|
@@ -137,7 +138,7 @@ export class ERC8004Bridge {
|
|
|
137
138
|
config.registryAddress ?? ERC8004_IDENTITY_REGISTRY[config.network];
|
|
138
139
|
|
|
139
140
|
if (registryAddress === ethers.ZeroAddress) {
|
|
140
|
-
|
|
141
|
+
sdkLogger.warn(
|
|
141
142
|
`[ERC8004] Registry not deployed on ${config.network}. Using zero address.`
|
|
142
143
|
);
|
|
143
144
|
}
|
|
@@ -327,7 +328,7 @@ export class ERC8004Bridge {
|
|
|
327
328
|
|
|
328
329
|
return agentIds;
|
|
329
330
|
} catch (error) {
|
|
330
|
-
|
|
331
|
+
sdkLogger.warn(`[ERC8004] Failed to get agents for owner ${owner}: ${error instanceof Error ? error.message : error}`);
|
|
331
332
|
return [];
|
|
332
333
|
}
|
|
333
334
|
}
|
|
@@ -417,7 +418,7 @@ export class ERC8004Bridge {
|
|
|
417
418
|
|
|
418
419
|
// Validate URL
|
|
419
420
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
|
420
|
-
|
|
421
|
+
sdkLogger.warn(`[ERC8004] Invalid agentURI scheme for ${agentId}: ${url}`);
|
|
421
422
|
return undefined;
|
|
422
423
|
}
|
|
423
424
|
|
|
@@ -434,7 +435,7 @@ export class ERC8004Bridge {
|
|
|
434
435
|
clearTimeout(timeoutId);
|
|
435
436
|
|
|
436
437
|
if (!response.ok) {
|
|
437
|
-
|
|
438
|
+
sdkLogger.warn(
|
|
438
439
|
`[ERC8004] Metadata fetch failed for ${agentId}: HTTP ${response.status}`
|
|
439
440
|
);
|
|
440
441
|
return undefined;
|
|
@@ -454,7 +455,7 @@ export class ERC8004Bridge {
|
|
|
454
455
|
: error.message
|
|
455
456
|
: 'unknown error';
|
|
456
457
|
|
|
457
|
-
|
|
458
|
+
sdkLogger.warn(`[ERC8004] Metadata fetch failed for ${agentId}: ${errorMessage}`);
|
|
458
459
|
return undefined;
|
|
459
460
|
}
|
|
460
461
|
}
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
ERC8004_REPUTATION_ABI,
|
|
51
51
|
ACTP_FEEDBACK_TAGS,
|
|
52
52
|
} from '../types/erc8004';
|
|
53
|
+
import { sdkLogger } from '../utils/Logger';
|
|
53
54
|
|
|
54
55
|
// ============================================================================
|
|
55
56
|
// Types
|
|
@@ -214,9 +215,8 @@ export class ReputationReporter {
|
|
|
214
215
|
config.registryAddress ?? ERC8004_REPUTATION_REGISTRY[config.network];
|
|
215
216
|
|
|
216
217
|
if (registryAddress === ethers.ZeroAddress) {
|
|
217
|
-
|
|
218
|
-
`[ERC8004] Reputation Registry not deployed on ${config.network}.
|
|
219
|
-
'Reports will fail.'
|
|
218
|
+
sdkLogger.warn(
|
|
219
|
+
`[ERC8004] Reputation Registry not deployed on ${config.network}. Reports will fail.`
|
|
220
220
|
);
|
|
221
221
|
}
|
|
222
222
|
|
|
@@ -257,7 +257,7 @@ export class ReputationReporter {
|
|
|
257
257
|
|
|
258
258
|
// Local dedup check
|
|
259
259
|
if (this.reportedTxIds.has(txId)) {
|
|
260
|
-
|
|
260
|
+
sdkLogger.warn(`[ERC8004] Already reported txId in this session: ${txId}`);
|
|
261
261
|
return null;
|
|
262
262
|
}
|
|
263
263
|
|
|
@@ -322,7 +322,7 @@ export class ReputationReporter {
|
|
|
322
322
|
|
|
323
323
|
// Local dedup check
|
|
324
324
|
if (this.reportedTxIds.has(txId)) {
|
|
325
|
-
|
|
325
|
+
sdkLogger.warn(`[ERC8004] Already reported txId in this session: ${txId}`);
|
|
326
326
|
return null;
|
|
327
327
|
}
|
|
328
328
|
|
|
@@ -392,9 +392,8 @@ export class ReputationReporter {
|
|
|
392
392
|
score: Number(summaryValue),
|
|
393
393
|
};
|
|
394
394
|
} catch (error) {
|
|
395
|
-
|
|
396
|
-
`[ERC8004] getAgentReputation failed for ${agentId}
|
|
397
|
-
error instanceof Error ? error.message : error
|
|
395
|
+
sdkLogger.error(
|
|
396
|
+
`[ERC8004] getAgentReputation failed for ${agentId}: ${error instanceof Error ? error.message : error}`
|
|
398
397
|
);
|
|
399
398
|
return null;
|
|
400
399
|
}
|
|
@@ -449,23 +448,20 @@ export class ReputationReporter {
|
|
|
449
448
|
|
|
450
449
|
// Check for common error cases
|
|
451
450
|
if (errorMessage.includes('insufficient funds')) {
|
|
452
|
-
|
|
453
|
-
`[ERC8004] ${method} failed for agent ${agentId}:
|
|
454
|
-
'Insufficient funds for gas. Signer needs ETH/native token.'
|
|
451
|
+
sdkLogger.error(
|
|
452
|
+
`[ERC8004] ${method} failed for agent ${agentId}: Insufficient funds for gas. Signer needs ETH/native token.`
|
|
455
453
|
);
|
|
456
454
|
} else if (errorMessage.includes('cannot be the agent owner')) {
|
|
457
|
-
|
|
458
|
-
`[ERC8004] ${method} failed for agent ${agentId}:
|
|
459
|
-
'Caller is agent owner. ERC-8004 requires different address.'
|
|
455
|
+
sdkLogger.error(
|
|
456
|
+
`[ERC8004] ${method} failed for agent ${agentId}: Caller is agent owner. ERC-8004 requires different address.`
|
|
460
457
|
);
|
|
461
458
|
} else if (errorMessage.includes('user rejected')) {
|
|
462
|
-
|
|
459
|
+
sdkLogger.warn(
|
|
463
460
|
`[ERC8004] ${method} cancelled by user for agent ${agentId}`
|
|
464
461
|
);
|
|
465
462
|
} else {
|
|
466
|
-
|
|
467
|
-
`[ERC8004] ${method} failed for agent ${agentId} (tx: ${txId}): `
|
|
468
|
-
errorMessage
|
|
463
|
+
sdkLogger.error(
|
|
464
|
+
`[ERC8004] ${method} failed for agent ${agentId} (tx: ${txId}): ${errorMessage}`
|
|
469
465
|
);
|
|
470
466
|
}
|
|
471
467
|
}
|
package/src/index.ts
CHANGED
|
@@ -178,6 +178,18 @@ export {
|
|
|
178
178
|
|
|
179
179
|
// Wallet
|
|
180
180
|
export { resolvePrivateKey, getCachedAddress } from './wallet/keystore';
|
|
181
|
+
export type {
|
|
182
|
+
IWalletProvider,
|
|
183
|
+
TransactionRequest as WalletTransactionRequest,
|
|
184
|
+
TransactionReceipt as WalletTransactionReceipt,
|
|
185
|
+
WalletInfo,
|
|
186
|
+
WalletTier,
|
|
187
|
+
BatchedPayParams,
|
|
188
|
+
BatchedPayResult,
|
|
189
|
+
} from './wallet/IWalletProvider';
|
|
190
|
+
export { EOAWalletProvider } from './wallet/EOAWalletProvider';
|
|
191
|
+
export { AutoWalletProvider } from './wallet/AutoWalletProvider';
|
|
192
|
+
export type { AutoWalletConfig } from './wallet/AutoWalletProvider';
|
|
181
193
|
|
|
182
194
|
// Helper utilities
|
|
183
195
|
export {
|
package/src/level1/Agent.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { RequestOptions, RequestResult, NetworkOption } from './types/Options';
|
|
|
19
19
|
import { PricingStrategy } from './pricing/PricingStrategy';
|
|
20
20
|
import { AgentLifecycleError, ServiceConfigError, ValidationError } from '../errors';
|
|
21
21
|
import { validateServiceName, validatePath, LRUCache } from '../utils/security';
|
|
22
|
-
import { Logger } from '../utils/Logger';
|
|
22
|
+
import { Logger, sdkLogger } from '../utils/Logger';
|
|
23
23
|
import { ServiceHash } from '../utils/Helpers';
|
|
24
24
|
import { Semaphore } from '../utils/Semaphore';
|
|
25
25
|
import { ProofGenerator } from '../protocol/ProofGenerator';
|
|
@@ -1311,21 +1311,21 @@ export class Agent extends EventEmitter {
|
|
|
1311
1311
|
log: {
|
|
1312
1312
|
debug: (message: string, meta?: any) => {
|
|
1313
1313
|
if (agent.config.logging?.level === 'debug') {
|
|
1314
|
-
|
|
1314
|
+
sdkLogger.debug(`[${job.id}] ${message}`, meta);
|
|
1315
1315
|
}
|
|
1316
1316
|
},
|
|
1317
1317
|
info: (message: string, meta?: any) => {
|
|
1318
1318
|
if (['debug', 'info'].includes(agent.config.logging?.level || 'info')) {
|
|
1319
|
-
|
|
1319
|
+
sdkLogger.info(`[${job.id}] ${message}`, meta);
|
|
1320
1320
|
}
|
|
1321
1321
|
},
|
|
1322
1322
|
warn: (message: string, meta?: any) => {
|
|
1323
1323
|
if (['debug', 'info', 'warn'].includes(agent.config.logging?.level || 'info')) {
|
|
1324
|
-
|
|
1324
|
+
sdkLogger.warn(`[${job.id}] ${message}`, meta);
|
|
1325
1325
|
}
|
|
1326
1326
|
},
|
|
1327
1327
|
error: (message: string, meta?: any) => {
|
|
1328
|
-
|
|
1328
|
+
sdkLogger.error(`[${job.id}] ${message}`, meta);
|
|
1329
1329
|
},
|
|
1330
1330
|
},
|
|
1331
1331
|
|
|
@@ -37,14 +37,25 @@ interface GasOptions {
|
|
|
37
37
|
export class ACTPKernel {
|
|
38
38
|
private contract: Contract;
|
|
39
39
|
private readonly gasSettings?: GasOptions;
|
|
40
|
+
/**
|
|
41
|
+
* Number of block confirmations to wait after each state-changing tx.
|
|
42
|
+
* Default: 2 (Base L2 reorg safety — ~4-6 s on Base's 2 s blocks).
|
|
43
|
+
* Set to 1 for faster feedback on testnet; never set to 0 in production.
|
|
44
|
+
*/
|
|
45
|
+
private readonly confirmations: number;
|
|
40
46
|
|
|
41
47
|
constructor(
|
|
42
48
|
private readonly address: string,
|
|
43
49
|
signer: Signer,
|
|
44
|
-
gasSettings?: GasOptions
|
|
50
|
+
gasSettings?: GasOptions,
|
|
51
|
+
confirmations: number = 2
|
|
45
52
|
) {
|
|
53
|
+
if (confirmations < 1) {
|
|
54
|
+
throw new Error(`confirmations must be >= 1, got ${confirmations}`);
|
|
55
|
+
}
|
|
46
56
|
this.contract = new Contract(address, ACTPKernelABI, signer);
|
|
47
57
|
this.gasSettings = gasSettings;
|
|
58
|
+
this.confirmations = confirmations;
|
|
48
59
|
}
|
|
49
60
|
|
|
50
61
|
/**
|
|
@@ -213,7 +224,7 @@ export class ACTPKernel {
|
|
|
213
224
|
txOptions
|
|
214
225
|
);
|
|
215
226
|
|
|
216
|
-
const receipt = await tx.wait(
|
|
227
|
+
const receipt = await tx.wait(this.confirmations);
|
|
217
228
|
if (!receipt) {
|
|
218
229
|
throw new Error('Transaction receipt not available');
|
|
219
230
|
}
|
|
@@ -280,7 +291,7 @@ export class ACTPKernel {
|
|
|
280
291
|
|
|
281
292
|
const tx = await transitionFunc(txId, newState, proof, txOptions);
|
|
282
293
|
|
|
283
|
-
await tx.wait(
|
|
294
|
+
await tx.wait(this.confirmations);
|
|
284
295
|
} catch (error: any) {
|
|
285
296
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
286
297
|
}
|
|
@@ -400,8 +411,7 @@ export class ACTPKernel {
|
|
|
400
411
|
|
|
401
412
|
const tx = await linkEscrowFunc(txId, escrowContract, escrowId, txOptions);
|
|
402
413
|
|
|
403
|
-
|
|
404
|
-
await tx.wait(2);
|
|
414
|
+
await tx.wait(this.confirmations);
|
|
405
415
|
} catch (error: any) {
|
|
406
416
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
407
417
|
}
|
|
@@ -437,7 +447,7 @@ export class ACTPKernel {
|
|
|
437
447
|
|
|
438
448
|
const tx = await releaseMilestoneFunc(txId, amount, txOptions);
|
|
439
449
|
|
|
440
|
-
await tx.wait(
|
|
450
|
+
await tx.wait(this.confirmations);
|
|
441
451
|
} catch (error: any) {
|
|
442
452
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
443
453
|
}
|
|
@@ -521,7 +531,7 @@ export class ACTPKernel {
|
|
|
521
531
|
|
|
522
532
|
const tx = await releaseEscrowFunc(txId, txOptions);
|
|
523
533
|
|
|
524
|
-
await tx.wait(
|
|
534
|
+
await tx.wait(this.confirmations);
|
|
525
535
|
} catch (error: any) {
|
|
526
536
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
527
537
|
}
|
|
@@ -669,7 +679,7 @@ export class ACTPKernel {
|
|
|
669
679
|
txOptions
|
|
670
680
|
);
|
|
671
681
|
|
|
672
|
-
await tx.wait(
|
|
682
|
+
await tx.wait(this.confirmations);
|
|
673
683
|
} catch (error: any) {
|
|
674
684
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
675
685
|
}
|
|
@@ -735,7 +745,7 @@ export class ACTPKernel {
|
|
|
735
745
|
txOptions
|
|
736
746
|
);
|
|
737
747
|
|
|
738
|
-
await tx.wait(
|
|
748
|
+
await tx.wait(this.confirmations);
|
|
739
749
|
} catch (error: any) {
|
|
740
750
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
741
751
|
}
|
|
@@ -789,7 +799,7 @@ export class ACTPKernel {
|
|
|
789
799
|
txOptions
|
|
790
800
|
);
|
|
791
801
|
|
|
792
|
-
await tx.wait(
|
|
802
|
+
await tx.wait(this.confirmations);
|
|
793
803
|
} catch (error: any) {
|
|
794
804
|
throw new TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
795
805
|
}
|
|
@@ -4,6 +4,20 @@ import { State, Transaction } from '../types';
|
|
|
4
4
|
/**
|
|
5
5
|
* EventMonitor - Listen to blockchain events
|
|
6
6
|
*
|
|
7
|
+
* ## Confirmation Policy
|
|
8
|
+
*
|
|
9
|
+
* Events received by EventMonitor are already confirmed. ACTPKernel waits
|
|
10
|
+
* for N block confirmations (default 2, configurable via `confirmations`
|
|
11
|
+
* parameter in BlockchainRuntimeConfig) before returning from state-changing
|
|
12
|
+
* operations. On Base L2 (~2 s blocks), the default means events arrive
|
|
13
|
+
* ~4-6 s after submission and are safe from reorgs.
|
|
14
|
+
*
|
|
15
|
+
* Confirmation flow:
|
|
16
|
+
* User calls ACTPKernel.createTransaction()
|
|
17
|
+
* → tx.wait(confirmations) blocks until N confirmations
|
|
18
|
+
* → Event emitted (already confirmed)
|
|
19
|
+
* → EventMonitor receives event (instant)
|
|
20
|
+
*
|
|
7
21
|
* SECURITY FIX (EVENT-MONITOR): Corrected event parameter order to match ABI.
|
|
8
22
|
* Per ACTPKernel.json, TransactionCreated signature is:
|
|
9
23
|
* (bytes32 indexed transactionId, address indexed requester, address indexed provider, uint256 amount, bytes32 serviceHash)
|
|
@@ -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;
|
|
@@ -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
|
}
|