@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.
Files changed (153) hide show
  1. package/README.md +45 -8
  2. package/dist/ACTPClient.d.ts +35 -1
  3. package/dist/ACTPClient.d.ts.map +1 -1
  4. package/dist/ACTPClient.js +156 -26
  5. package/dist/ACTPClient.js.map +1 -1
  6. package/dist/adapters/AdapterRouter.d.ts.map +1 -1
  7. package/dist/adapters/AdapterRouter.js.map +1 -1
  8. package/dist/adapters/BasicAdapter.d.ts +10 -1
  9. package/dist/adapters/BasicAdapter.d.ts.map +1 -1
  10. package/dist/adapters/BasicAdapter.js +36 -1
  11. package/dist/adapters/BasicAdapter.js.map +1 -1
  12. package/dist/cli/commands/init.d.ts +1 -0
  13. package/dist/cli/commands/init.d.ts.map +1 -1
  14. package/dist/cli/commands/init.js +210 -18
  15. package/dist/cli/commands/init.js.map +1 -1
  16. package/dist/cli/commands/publish.d.ts.map +1 -1
  17. package/dist/cli/commands/publish.js.map +1 -1
  18. package/dist/cli/commands/register.d.ts +16 -0
  19. package/dist/cli/commands/register.d.ts.map +1 -0
  20. package/dist/cli/commands/register.js +211 -0
  21. package/dist/cli/commands/register.js.map +1 -0
  22. package/dist/cli/index.js +3 -0
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/cli/utils/config.d.ts +6 -0
  25. package/dist/cli/utils/config.d.ts.map +1 -1
  26. package/dist/cli/utils/config.js.map +1 -1
  27. package/dist/config/networks.d.ts +20 -4
  28. package/dist/config/networks.d.ts.map +1 -1
  29. package/dist/config/networks.js +59 -27
  30. package/dist/config/networks.js.map +1 -1
  31. package/dist/config/publishPipeline.d.ts +14 -0
  32. package/dist/config/publishPipeline.d.ts.map +1 -1
  33. package/dist/config/publishPipeline.js +2 -1
  34. package/dist/config/publishPipeline.js.map +1 -1
  35. package/dist/erc8004/ERC8004Bridge.d.ts.map +1 -1
  36. package/dist/erc8004/ERC8004Bridge.js +6 -5
  37. package/dist/erc8004/ERC8004Bridge.js.map +1 -1
  38. package/dist/erc8004/ReputationReporter.d.ts.map +1 -1
  39. package/dist/erc8004/ReputationReporter.js +9 -12
  40. package/dist/erc8004/ReputationReporter.js.map +1 -1
  41. package/dist/index.d.ts +4 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +7 -3
  44. package/dist/index.js.map +1 -1
  45. package/dist/level1/Agent.js +4 -4
  46. package/dist/level1/Agent.js.map +1 -1
  47. package/dist/protocol/ACTPKernel.d.ts +7 -1
  48. package/dist/protocol/ACTPKernel.d.ts.map +1 -1
  49. package/dist/protocol/ACTPKernel.js +13 -10
  50. package/dist/protocol/ACTPKernel.js.map +1 -1
  51. package/dist/protocol/EventMonitor.d.ts +14 -0
  52. package/dist/protocol/EventMonitor.d.ts.map +1 -1
  53. package/dist/protocol/EventMonitor.js +14 -0
  54. package/dist/protocol/EventMonitor.js.map +1 -1
  55. package/dist/runtime/BlockchainRuntime.d.ts +5 -0
  56. package/dist/runtime/BlockchainRuntime.d.ts.map +1 -1
  57. package/dist/runtime/BlockchainRuntime.js +1 -1
  58. package/dist/runtime/BlockchainRuntime.js.map +1 -1
  59. package/dist/storage/ArchiveBundleBuilder.d.ts.map +1 -1
  60. package/dist/storage/ArchiveBundleBuilder.js.map +1 -1
  61. package/dist/storage/ArweaveClient.d.ts.map +1 -1
  62. package/dist/storage/ArweaveClient.js +2 -0
  63. package/dist/storage/ArweaveClient.js.map +1 -1
  64. package/dist/storage/FilebaseClient.d.ts.map +1 -1
  65. package/dist/storage/FilebaseClient.js +2 -0
  66. package/dist/storage/FilebaseClient.js.map +1 -1
  67. package/dist/utils/ErrorRecoveryGuide.d.ts.map +1 -1
  68. package/dist/utils/ErrorRecoveryGuide.js +3 -2
  69. package/dist/utils/ErrorRecoveryGuide.js.map +1 -1
  70. package/dist/utils/IPFSClient.d.ts +3 -2
  71. package/dist/utils/IPFSClient.d.ts.map +1 -1
  72. package/dist/utils/IPFSClient.js +7 -5
  73. package/dist/utils/IPFSClient.js.map +1 -1
  74. package/dist/utils/computeTypeHash.js +1 -3
  75. package/dist/utils/computeTypeHash.js.map +1 -1
  76. package/dist/utils/retry.d.ts.map +1 -1
  77. package/dist/utils/retry.js +0 -1
  78. package/dist/utils/retry.js.map +1 -1
  79. package/dist/utils/validation.d.ts +2 -2
  80. package/dist/utils/validation.d.ts.map +1 -1
  81. package/dist/utils/validation.js +2 -2
  82. package/dist/utils/validation.js.map +1 -1
  83. package/dist/wallet/AutoWalletProvider.d.ts +77 -0
  84. package/dist/wallet/AutoWalletProvider.d.ts.map +1 -0
  85. package/dist/wallet/AutoWalletProvider.js +197 -0
  86. package/dist/wallet/AutoWalletProvider.js.map +1 -0
  87. package/dist/wallet/EOAWalletProvider.d.ts +21 -0
  88. package/dist/wallet/EOAWalletProvider.d.ts.map +1 -0
  89. package/dist/wallet/EOAWalletProvider.js +57 -0
  90. package/dist/wallet/EOAWalletProvider.js.map +1 -0
  91. package/dist/wallet/IWalletProvider.d.ts +115 -0
  92. package/dist/wallet/IWalletProvider.d.ts.map +1 -0
  93. package/dist/wallet/IWalletProvider.js +12 -0
  94. package/dist/wallet/IWalletProvider.js.map +1 -0
  95. package/dist/wallet/aa/BundlerClient.d.ts +70 -0
  96. package/dist/wallet/aa/BundlerClient.d.ts.map +1 -0
  97. package/dist/wallet/aa/BundlerClient.js +183 -0
  98. package/dist/wallet/aa/BundlerClient.js.map +1 -0
  99. package/dist/wallet/aa/DualNonceManager.d.ts +55 -0
  100. package/dist/wallet/aa/DualNonceManager.d.ts.map +1 -0
  101. package/dist/wallet/aa/DualNonceManager.js +131 -0
  102. package/dist/wallet/aa/DualNonceManager.js.map +1 -0
  103. package/dist/wallet/aa/PaymasterClient.d.ts +52 -0
  104. package/dist/wallet/aa/PaymasterClient.d.ts.map +1 -0
  105. package/dist/wallet/aa/PaymasterClient.js +115 -0
  106. package/dist/wallet/aa/PaymasterClient.js.map +1 -0
  107. package/dist/wallet/aa/TransactionBatcher.d.ts +87 -0
  108. package/dist/wallet/aa/TransactionBatcher.d.ts.map +1 -0
  109. package/dist/wallet/aa/TransactionBatcher.js +148 -0
  110. package/dist/wallet/aa/TransactionBatcher.js.map +1 -0
  111. package/dist/wallet/aa/UserOpBuilder.d.ts +71 -0
  112. package/dist/wallet/aa/UserOpBuilder.d.ts.map +1 -0
  113. package/dist/wallet/aa/UserOpBuilder.js +196 -0
  114. package/dist/wallet/aa/UserOpBuilder.js.map +1 -0
  115. package/dist/wallet/aa/constants.d.ts +54 -0
  116. package/dist/wallet/aa/constants.d.ts.map +1 -0
  117. package/dist/wallet/aa/constants.js +18 -0
  118. package/dist/wallet/aa/constants.js.map +1 -0
  119. package/package.json +4 -2
  120. package/src/ACTPClient.ts +217 -31
  121. package/src/adapters/AdapterRouter.ts +0 -1
  122. package/src/adapters/BasicAdapter.ts +41 -1
  123. package/src/cli/commands/init.ts +247 -19
  124. package/src/cli/commands/publish.ts +1 -2
  125. package/src/cli/commands/register.ts +233 -0
  126. package/src/cli/index.ts +4 -0
  127. package/src/cli/utils/config.ts +9 -0
  128. package/src/config/networks.ts +82 -27
  129. package/src/config/publishPipeline.ts +2 -2
  130. package/src/erc8004/ERC8004Bridge.ts +6 -5
  131. package/src/erc8004/ReputationReporter.ts +14 -18
  132. package/src/index.ts +12 -0
  133. package/src/level1/Agent.ts +5 -5
  134. package/src/protocol/ACTPKernel.ts +20 -10
  135. package/src/protocol/EventMonitor.ts +14 -0
  136. package/src/runtime/BlockchainRuntime.ts +7 -1
  137. package/src/storage/ArchiveBundleBuilder.ts +0 -2
  138. package/src/storage/ArweaveClient.ts +2 -1
  139. package/src/storage/FilebaseClient.ts +3 -3
  140. package/src/utils/ErrorRecoveryGuide.ts +4 -2
  141. package/src/utils/IPFSClient.ts +9 -7
  142. package/src/utils/computeTypeHash.ts +1 -3
  143. package/src/utils/retry.ts +0 -1
  144. package/src/utils/validation.ts +2 -2
  145. package/src/wallet/AutoWalletProvider.ts +294 -0
  146. package/src/wallet/EOAWalletProvider.ts +69 -0
  147. package/src/wallet/IWalletProvider.ts +133 -0
  148. package/src/wallet/aa/BundlerClient.ts +273 -0
  149. package/src/wallet/aa/DualNonceManager.ts +163 -0
  150. package/src/wallet/aa/PaymasterClient.ts +173 -0
  151. package/src/wallet/aa/TransactionBatcher.ts +240 -0
  152. package/src/wallet/aa/UserOpBuilder.ts +246 -0
  153. package/src/wallet/aa/constants.ts +60 -0
@@ -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
- // AIP-7 Agent Registry (deployed 2025-12-11)
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
- // X402Relay - atomic payment fee splitting (TODO: deploy and set address)
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
- // Deployed 2026-02-03
103
- actpKernel: '0xeaE4D6925510284dbC45C8C64bb8104a079D4c60',
104
- escrowVault: '0xb7bCadF7F26f0761995d95105DFb2346F81AF02D',
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
- // AIP-7 contracts
110
- agentRegistry: '0xbf9Aa0FC291A06A4dFA943c3E0Ad41E7aE20DF02',
111
- archiveTreasury: '0x64B8f93fef2D2E749F5E88586753343F73246012',
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, computeConfigHashFromParts, serializeAgirailsMd } from './agirailsmd';
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
- console.warn(
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
- console.warn(`[ERC8004] Failed to get agents for owner ${owner}:`, error);
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
- console.warn(`[ERC8004] Invalid agentURI scheme for ${agentId}: ${url}`);
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
- console.warn(
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
- console.warn(`[ERC8004] Metadata fetch failed for ${agentId}: ${errorMessage}`);
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
- console.warn(
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
- console.warn(`[ERC8004] Already reported txId in this session: ${txId}`);
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
- console.warn(`[ERC8004] Already reported txId in this session: ${txId}`);
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
- console.error(
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
- console.error(
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
- console.error(
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
- console.warn(
459
+ sdkLogger.warn(
463
460
  `[ERC8004] ${method} cancelled by user for agent ${agentId}`
464
461
  );
465
462
  } else {
466
- console.error(
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 {
@@ -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
- console.debug(`[${job.id}] ${message}`, meta);
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
- console.info(`[${job.id}] ${message}`, meta);
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
- console.warn(`[${job.id}] ${message}`, meta);
1324
+ sdkLogger.warn(`[${job.id}] ${message}`, meta);
1325
1325
  }
1326
1326
  },
1327
1327
  error: (message: string, meta?: any) => {
1328
- console.error(`[${job.id}] ${message}`, meta);
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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
- // Wait for 2 confirmations to ensure state is updated on RPC nodes (Base Sepolia reorg safety)
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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(2); // Wait for 2 confirmations (Base L2 reorg safety)
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, GetObjectCommand, HeadObjectCommand } from '@aws-sdk/client-s3';
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
- console.error(ErrorRecoveryGuide.formatGuidance(error));
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
- console.log(
662
+ sdkLogger.info(
661
663
  `Retrying (${attempts}/${retryParams.maxRetries}) after ${retryParams.delayMs}ms...`
662
664
  );
663
665
  await new Promise((resolve) =>
@@ -74,8 +74,8 @@ export interface IPFSClientConfig {
74
74
  allowedProtocols?: string[];
75
75
 
76
76
  /**
77
- * SECURITY FIX (MEDIUM-3): Allow localhost URLs
78
- * Default: true (required for local IPFS daemon)
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 ?? true, config.allowedProtocols);
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 ?? true,
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
  }