@agether/sdk 1.11.2 → 2.1.0

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/index.js CHANGED
@@ -31,19 +31,26 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ACCOUNT_FACTORY_ABI: () => ACCOUNT_FACTORY_ABI,
34
- AGENT_ACCOUNT_ABI: () => AGENT_ACCOUNT_ABI,
35
34
  AGENT_REPUTATION_ABI: () => AGENT_REPUTATION_ABI,
35
+ AGETHER_4337_FACTORY_ABI: () => AGETHER_4337_FACTORY_ABI,
36
+ AGETHER_8004_SCORER_ABI: () => AGETHER_8004_SCORER_ABI,
37
+ AGETHER_8004_VALIDATION_MODULE_ABI: () => AGETHER_8004_VALIDATION_MODULE_ABI,
38
+ AGETHER_HOOK_MULTIPLEXER_ABI: () => AGETHER_HOOK_MULTIPLEXER_ABI,
36
39
  AgentIdentityClient: () => AgentIdentityClient,
37
40
  AgentNotApprovedError: () => AgentNotApprovedError,
38
41
  AgetherClient: () => AgetherClient,
39
42
  AgetherError: () => AgetherError,
40
43
  ChainId: () => ChainId,
44
+ ENTRYPOINT_V07_ABI: () => ENTRYPOINT_V07_ABI,
41
45
  ERC20_ABI: () => ERC20_ABI,
46
+ ERC8004_VALIDATION_MODULE_ABI: () => ERC8004_VALIDATION_MODULE_ABI,
47
+ HOOK_MULTIPLEXER_ABI: () => HOOK_MULTIPLEXER_ABI,
42
48
  IDENTITY_REGISTRY_ABI: () => IDENTITY_REGISTRY_ABI,
43
49
  InsufficientBalanceError: () => InsufficientBalanceError,
44
- KYA_HOOK_ABI: () => KYA_HOOK_ABI,
45
50
  MORPHO_BLUE_ABI: () => MORPHO_BLUE_ABI,
46
51
  MorphoClient: () => MorphoClient,
52
+ SAFE7579_ACCOUNT_ABI: () => SAFE7579_ACCOUNT_ABI,
53
+ SAFE_AGENT_FACTORY_ABI: () => SAFE_AGENT_FACTORY_ABI,
47
54
  ScoringClient: () => ScoringClient,
48
55
  ScoringRejectedError: () => ScoringRejectedError,
49
56
  VALIDATION_REGISTRY_ABI: () => VALIDATION_REGISTRY_ABI,
@@ -120,40 +127,45 @@ var IDENTITY_REGISTRY_ABI = [
120
127
  "function register() returns (uint256 agentId)",
121
128
  "event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)"
122
129
  ];
123
- var ACCOUNT_FACTORY_ABI = [
130
+ var AGETHER_4337_FACTORY_ABI = [
124
131
  "function getAccount(uint256 agentId) view returns (address)",
125
132
  "function accountExists(uint256 agentId) view returns (bool)",
126
- "function predictAddress(uint256 agentId) view returns (address)",
127
133
  "function totalAccounts() view returns (uint256)",
128
134
  "function getAgentId(address account) view returns (uint256)",
129
- "function createAccount(uint256 agentId) returns (address account)",
130
- "function protocolHook() view returns (address)",
135
+ "function getAgentIdByIndex(uint256 index) view returns (uint256)",
136
+ "function getAllAgentIds() view returns (uint256[])",
137
+ "function createAccount(uint256 agentId) returns (address safeAccount)",
131
138
  "function identityRegistry() view returns (address)",
132
- "event AccountCreated(uint256 indexed agentId, address indexed account, address indexed owner)"
139
+ "function validationModule() view returns (address)",
140
+ "function hookMultiplexer() view returns (address)",
141
+ "function safeSingleton() view returns (address)",
142
+ "function safe7579() view returns (address)",
143
+ "function bootstrap() view returns (address)",
144
+ "event AccountCreated(uint256 indexed agentId, address indexed safeAccount, address indexed owner)"
133
145
  ];
134
- var AGENT_ACCOUNT_ABI = [
135
- "function agentId() view returns (uint256)",
146
+ var SAFE_AGENT_FACTORY_ABI = AGETHER_4337_FACTORY_ABI;
147
+ var ACCOUNT_FACTORY_ABI = AGETHER_4337_FACTORY_ABI;
148
+ var AGETHER_8004_VALIDATION_MODULE_ABI = [
149
+ // View
150
+ "function getConfig(address account) view returns (address registry, uint256 agentId)",
151
+ "function getOwner(address account) view returns (address)",
152
+ "function isInstalled(address account) view returns (bool)",
153
+ "function isKYAApproved(address account) view returns (bool)",
154
+ "function validationRegistry() view returns (address)",
136
155
  "function owner() view returns (address)",
137
- "function factory() view returns (address)",
138
- "function identityRegistry() view returns (address)",
139
- "function balanceOf(address token) view returns (uint256)",
140
- "function ethBalance() view returns (uint256)",
141
- // ERC-7579 execution
142
- "function execute(bytes32 mode, bytes executionCalldata) payable",
143
- "function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
144
- // ERC-7579 module management
145
- "function installModule(uint256 moduleTypeId, address module, bytes initData) payable",
146
- "function uninstallModule(uint256 moduleTypeId, address module, bytes deInitData) payable",
147
- "function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
148
- "function hook() view returns (address)",
149
- // Funding (direct, no execution needed)
150
- "function fund(address token, uint256 amount)",
151
- "function withdraw(address token, uint256 amount, address to)",
152
- "function withdrawETH(uint256 amount, address to)",
153
- // EIP-1271
154
- "function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
156
+ // Admin (via TimelockController)
157
+ "function setValidationRegistry(address registry_)"
158
+ ];
159
+ var ERC8004_VALIDATION_MODULE_ABI = AGETHER_8004_VALIDATION_MODULE_ABI;
160
+ var AGETHER_HOOK_MULTIPLEXER_ABI = [
161
+ "function getHooks() view returns (address[])",
162
+ "function hookCount() view returns (uint256)",
163
+ "function owner() view returns (address)",
164
+ "function addHook(address hook)",
165
+ "function removeHook(address hook)"
155
166
  ];
156
- var AGENT_REPUTATION_ABI = [
167
+ var HOOK_MULTIPLEXER_ABI = AGETHER_HOOK_MULTIPLEXER_ABI;
168
+ var AGETHER_8004_SCORER_ABI = [
157
169
  "function getCreditScore(uint256 agentId) view returns (uint256)",
158
170
  "function getAttestation(uint256 agentId) view returns (tuple(uint256 score, uint256 timestamp, address signer))",
159
171
  "function isScoreFresh(uint256 agentId) view returns (bool fresh, uint256 age)",
@@ -163,6 +175,7 @@ var AGENT_REPUTATION_ABI = [
163
175
  "function setOracleSigner(address signer_)",
164
176
  "event ScoreUpdated(uint256 indexed agentId, uint256 score, uint256 timestamp, address signer)"
165
177
  ];
178
+ var AGENT_REPUTATION_ABI = AGETHER_8004_SCORER_ABI;
166
179
  var VALIDATION_REGISTRY_ABI = [
167
180
  "function isAgentCodeApproved(uint256 agentId) view returns (bool)",
168
181
  "function isAgentCodeApprovedForTag(uint256 agentId, string tag) view returns (bool)",
@@ -197,57 +210,113 @@ var ERC20_ABI = [
197
210
  "function symbol() view returns (string)",
198
211
  "function name() view returns (string)"
199
212
  ];
200
- var KYA_HOOK_ABI = [
201
- "function validationRegistry() view returns (address)",
202
- "function setValidationRegistry(address newRegistry)"
213
+ var ENTRYPOINT_V07_ABI = [
214
+ "function handleOps(tuple(address sender, uint256 nonce, bytes initCode, bytes callData, bytes32 accountGasLimits, uint256 preVerificationGas, bytes32 gasFees, bytes paymasterAndData, bytes signature)[] ops, address payable beneficiary)",
215
+ "function getUserOpHash(tuple(address sender, uint256 nonce, bytes initCode, bytes callData, bytes32 accountGasLimits, uint256 preVerificationGas, bytes32 gasFees, bytes paymasterAndData, bytes signature) userOp) view returns (bytes32)",
216
+ "function getNonce(address sender, uint192 key) view returns (uint256 nonce)",
217
+ "function balanceOf(address account) view returns (uint256)",
218
+ "function depositTo(address account) payable",
219
+ "event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed)"
220
+ ];
221
+ var SAFE7579_ACCOUNT_ABI = [
222
+ // ERC-7579 execution (called via UserOp through Safe7579 fallback)
223
+ "function execute(bytes32 mode, bytes executionCalldata) payable",
224
+ "function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
225
+ // ERC-7579 module queries
226
+ "function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
227
+ // EIP-1271
228
+ "function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
203
229
  ];
204
230
 
205
231
  // src/utils/config.ts
232
+ var ZERO = "0x0000000000000000000000000000000000000000";
233
+ var ENTRYPOINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
234
+ var ERC8004_IDENTITY_REGISTRY = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
235
+ var ERC8004_IDENTITY_REGISTRY_TESTNET = "0x8004A818BFB912233c491871b3d84c89A494BD9e";
236
+ var MORPHO_BLUE = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
237
+ var SAFE_SINGLETON = "0x41675C099F32341bf84BFc5382aF534df5C7461a";
238
+ var SAFE_PROXY_FACTORY = "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67";
239
+ var SAFE7579 = "0x7579EE8307284F293B1927136486880611F20002";
206
240
  var CONTRACT_ADDRESSES = {
207
241
  [1 /* Ethereum */]: {
208
- accountFactory: "0x0000000000000000000000000000000000000000",
209
- validationRegistry: "0x0000000000000000000000000000000000000000",
210
- agentReputation: "0x0000000000000000000000000000000000000000",
211
- kyaHook: "0x0000000000000000000000000000000000000000",
242
+ safeSingleton: SAFE_SINGLETON,
243
+ safeProxyFactory: SAFE_PROXY_FACTORY,
244
+ safe7579: SAFE7579,
245
+ entryPoint: ENTRYPOINT_V07,
246
+ agether4337Factory: ZERO,
247
+ agether7579Bootstrap: ZERO,
248
+ erc8004ValidationModule: ZERO,
249
+ agetherHookMultiplexer: ZERO,
250
+ validationRegistry: ZERO,
251
+ agether8004Scorer: ZERO,
252
+ timelockController: ZERO,
212
253
  usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
213
- identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
214
- morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
254
+ identityRegistry: ERC8004_IDENTITY_REGISTRY,
255
+ morphoBlue: MORPHO_BLUE
215
256
  },
216
257
  [8453 /* Base */]: {
217
- accountFactory: "0x89a8758E60A56EcB47247D92E05447eFd450d6Bf",
218
- validationRegistry: "0x6f76cF69B71Dc5F9A414BCEe4583b12738E47985",
219
- agentReputation: "0xe88f3419a2dbac70e3aF6E487b0C63e8301C6A87",
220
- kyaHook: "0x28e50Aa9eD517E369b2806928709B44062aD9821",
258
+ safeSingleton: SAFE_SINGLETON,
259
+ safeProxyFactory: SAFE_PROXY_FACTORY,
260
+ safe7579: SAFE7579,
261
+ entryPoint: ENTRYPOINT_V07,
262
+ agether4337Factory: "0x7B23470dCD65b8fEA3Bf49466860b3A55D56268C",
263
+ agether7579Bootstrap: "0x62d34D22D379367EEDcb7D1E4dE899A654E982D0",
264
+ erc8004ValidationModule: "0xfC6ccFd12e163460C7Ef92d38DC0be6C6cA10f6C",
265
+ agetherHookMultiplexer: "0x094FE93a8b733a97a6945530cA83058CaCbf5278",
266
+ validationRegistry: ZERO,
267
+ agether8004Scorer: "0x9f0084E5c941365149c8953133cF062E33a19b8d",
268
+ timelockController: "0x2807912DA2a7278AF883a376bE15bBBf3ab99f52",
221
269
  usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
222
- identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
223
- morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
270
+ identityRegistry: ERC8004_IDENTITY_REGISTRY,
271
+ morphoBlue: MORPHO_BLUE
224
272
  },
225
273
  [84532 /* BaseSepolia */]: {
226
- accountFactory: "0x0000000000000000000000000000000000000000",
227
- validationRegistry: "0x0000000000000000000000000000000000000000",
228
- agentReputation: "0x0000000000000000000000000000000000000000",
229
- kyaHook: "0x0000000000000000000000000000000000000000",
274
+ safeSingleton: SAFE_SINGLETON,
275
+ safeProxyFactory: SAFE_PROXY_FACTORY,
276
+ safe7579: SAFE7579,
277
+ entryPoint: ENTRYPOINT_V07,
278
+ agether4337Factory: ZERO,
279
+ agether7579Bootstrap: ZERO,
280
+ erc8004ValidationModule: ZERO,
281
+ agetherHookMultiplexer: ZERO,
282
+ validationRegistry: ZERO,
283
+ agether8004Scorer: ZERO,
284
+ timelockController: ZERO,
230
285
  usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
231
- identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
232
- morphoBlue: "0x0000000000000000000000000000000000000000"
286
+ identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
287
+ morphoBlue: ZERO
233
288
  },
234
289
  [11155111 /* Sepolia */]: {
235
- accountFactory: "0x0000000000000000000000000000000000000000",
236
- validationRegistry: "0x0000000000000000000000000000000000000000",
237
- agentReputation: "0x0000000000000000000000000000000000000000",
238
- kyaHook: "0x0000000000000000000000000000000000000000",
290
+ safeSingleton: SAFE_SINGLETON,
291
+ safeProxyFactory: SAFE_PROXY_FACTORY,
292
+ safe7579: SAFE7579,
293
+ entryPoint: ENTRYPOINT_V07,
294
+ agether4337Factory: ZERO,
295
+ agether7579Bootstrap: ZERO,
296
+ erc8004ValidationModule: ZERO,
297
+ agetherHookMultiplexer: ZERO,
298
+ validationRegistry: ZERO,
299
+ agether8004Scorer: ZERO,
300
+ timelockController: ZERO,
239
301
  usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
240
- identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
241
- morphoBlue: "0x0000000000000000000000000000000000000000"
302
+ identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
303
+ morphoBlue: ZERO
242
304
  },
243
305
  [31337 /* Hardhat */]: {
244
- accountFactory: "0x0000000000000000000000000000000000000000",
245
- validationRegistry: "0x0000000000000000000000000000000000000000",
246
- agentReputation: "0x0000000000000000000000000000000000000000",
247
- kyaHook: "0x0000000000000000000000000000000000000000",
306
+ safeSingleton: SAFE_SINGLETON,
307
+ safeProxyFactory: SAFE_PROXY_FACTORY,
308
+ safe7579: SAFE7579,
309
+ entryPoint: ENTRYPOINT_V07,
310
+ agether4337Factory: ZERO,
311
+ agether7579Bootstrap: ZERO,
312
+ erc8004ValidationModule: ZERO,
313
+ agetherHookMultiplexer: ZERO,
314
+ validationRegistry: ZERO,
315
+ agether8004Scorer: ZERO,
316
+ timelockController: ZERO,
248
317
  usdc: "0x56d4d6aEe0278c5Df2FA23Ecb32eC146C9446FDf",
249
- identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
250
- morphoBlue: "0x0000000000000000000000000000000000000000"
318
+ identityRegistry: ERC8004_IDENTITY_REGISTRY,
319
+ morphoBlue: ZERO
251
320
  }
252
321
  };
253
322
  var RPC_URLS = {
@@ -292,9 +361,9 @@ var AgetherClient = class _AgetherClient {
292
361
  this.agentId = options.agentId;
293
362
  const provider = options.signer.provider;
294
363
  if (!provider) throw new AgetherError("Signer must have a provider", "NO_PROVIDER");
295
- this.accountFactory = new import_ethers.Contract(
296
- options.config.contracts.accountFactory,
297
- ACCOUNT_FACTORY_ABI,
364
+ this.agether4337Factory = new import_ethers.Contract(
365
+ options.config.contracts.agether4337Factory,
366
+ AGETHER_4337_FACTORY_ABI,
298
367
  options.signer
299
368
  );
300
369
  this.identityRegistry = new import_ethers.Contract(
@@ -302,14 +371,14 @@ var AgetherClient = class _AgetherClient {
302
371
  IDENTITY_REGISTRY_ABI,
303
372
  provider
304
373
  );
305
- this.validationRegistry = new import_ethers.Contract(
306
- options.config.contracts.validationRegistry,
307
- VALIDATION_REGISTRY_ABI,
374
+ this.agether8004Scorer = new import_ethers.Contract(
375
+ options.config.contracts.agether8004Scorer,
376
+ AGETHER_8004_SCORER_ABI,
308
377
  provider
309
378
  );
310
- this.agentReputation = new import_ethers.Contract(
311
- options.config.contracts.agentReputation,
312
- AGENT_REPUTATION_ABI,
379
+ this.validationModule = new import_ethers.Contract(
380
+ options.config.contracts.erc8004ValidationModule,
381
+ AGETHER_8004_VALIDATION_MODULE_ABI,
313
382
  provider
314
383
  );
315
384
  }
@@ -322,26 +391,26 @@ var AgetherClient = class _AgetherClient {
322
391
  }
323
392
  // Account Management
324
393
  async createAccount() {
325
- const tx = await this.accountFactory.createAccount(this.agentId);
394
+ const tx = await this.agether4337Factory.createAccount(this.agentId);
326
395
  const receipt = await tx.wait();
327
396
  const event = receipt.logs.map((log) => {
328
397
  try {
329
- return this.accountFactory.interface.parseLog(log);
398
+ return this.agether4337Factory.interface.parseLog(log);
330
399
  } catch (e) {
331
400
  console.warn("[agether] createAccount parseLog skip:", e instanceof Error ? e.message : e);
332
401
  return null;
333
402
  }
334
403
  }).find((e) => e?.name === "AccountCreated");
335
404
  if (event) {
336
- this.accountAddress = event.args.account;
405
+ this.accountAddress = event.args.safeAccount;
337
406
  } else {
338
- this.accountAddress = await this.accountFactory.getAccount(this.agentId);
407
+ this.accountAddress = await this.agether4337Factory.getAccount(this.agentId);
339
408
  }
340
409
  return this.accountAddress;
341
410
  }
342
411
  async getAccountAddress() {
343
412
  if (this.accountAddress) return this.accountAddress;
344
- const addr = await this.accountFactory.getAccount(this.agentId);
413
+ const addr = await this.agether4337Factory.getAccount(this.agentId);
345
414
  if (addr === import_ethers.ethers.ZeroAddress) {
346
415
  throw new AgetherError("No account found. Create one with createAccount().", "NO_ACCOUNT");
347
416
  }
@@ -349,10 +418,7 @@ var AgetherClient = class _AgetherClient {
349
418
  return addr;
350
419
  }
351
420
  async accountExists() {
352
- return this.accountFactory.accountExists(this.agentId);
353
- }
354
- async predictAddress() {
355
- return this.accountFactory.predictAddress(this.agentId);
421
+ return this.agether4337Factory.accountExists(this.agentId);
356
422
  }
357
423
  // Balances
358
424
  async getBalances() {
@@ -374,10 +440,14 @@ var AgetherClient = class _AgetherClient {
374
440
  usdc: import_ethers.ethers.formatUnits(acctUsdc, 6)
375
441
  };
376
442
  } catch (e) {
377
- console.warn("[agether] getBalances: no AgentAccount or fetch failed:", e instanceof Error ? e.message : e);
443
+ console.warn("[agether] getBalances: no Safe account or fetch failed:", e instanceof Error ? e.message : e);
378
444
  }
379
445
  return result;
380
446
  }
447
+ /**
448
+ * Fund the Safe account with USDC from EOA.
449
+ * This is a simple ERC-20 transfer (does NOT require a UserOp).
450
+ */
381
451
  async fundAccount(usdcAmount) {
382
452
  const acctAddr = await this.getAccountAddress();
383
453
  const usdc = new import_ethers.Contract(this.config.contracts.usdc, ERC20_ABI, this.signer);
@@ -391,37 +461,30 @@ var AgetherClient = class _AgetherClient {
391
461
  gasUsed: receipt.gasUsed
392
462
  };
393
463
  }
394
- async withdrawUsdc(usdcAmount) {
395
- const acctAddr = await this.getAccountAddress();
396
- const account = new import_ethers.Contract(acctAddr, AGENT_ACCOUNT_ABI, this.signer);
397
- const amount = import_ethers.ethers.parseUnits(usdcAmount, 6);
398
- const eoaAddr = await this.signer.getAddress();
399
- const tx = await account.withdraw(this.config.contracts.usdc, amount, eoaAddr);
400
- const receipt = await tx.wait();
401
- return {
402
- txHash: receipt.hash,
403
- blockNumber: receipt.blockNumber,
404
- status: receipt.status === 1 ? "success" : "failed",
405
- gasUsed: receipt.gasUsed
406
- };
407
- }
408
- async withdrawEth(ethAmount) {
409
- const acctAddr = await this.getAccountAddress();
410
- const account = new import_ethers.Contract(acctAddr, AGENT_ACCOUNT_ABI, this.signer);
411
- const amount = import_ethers.ethers.parseEther(ethAmount);
412
- const eoaAddr = await this.signer.getAddress();
413
- const tx = await account.withdrawETH(amount, eoaAddr);
414
- const receipt = await tx.wait();
415
- return {
416
- txHash: receipt.hash,
417
- blockNumber: receipt.blockNumber,
418
- status: receipt.status === 1 ? "success" : "failed",
419
- gasUsed: receipt.gasUsed
420
- };
421
- }
422
464
  // Identity & Validation
465
+ /**
466
+ * Check if the KYA gate is active on the validation module.
467
+ * If validationRegistry is not set, all txs pass (KYA disabled).
468
+ */
469
+ async isKyaRequired() {
470
+ try {
471
+ const registryAddr = await this.validationModule.validationRegistry();
472
+ return registryAddr !== import_ethers.ethers.ZeroAddress;
473
+ } catch {
474
+ return false;
475
+ }
476
+ }
477
+ /**
478
+ * Check if this agent's code is KYA-approved.
479
+ * Uses the ERC8004ValidationModule.isKYAApproved(account) view.
480
+ */
423
481
  async isKyaApproved() {
424
- return this.validationRegistry.isAgentCodeApproved(this.agentId);
482
+ try {
483
+ const acctAddr = await this.getAccountAddress();
484
+ return this.validationModule.isKYAApproved(acctAddr);
485
+ } catch {
486
+ return false;
487
+ }
425
488
  }
426
489
  async identityExists() {
427
490
  try {
@@ -437,14 +500,14 @@ var AgetherClient = class _AgetherClient {
437
500
  }
438
501
  // Reputation
439
502
  async getCreditScore() {
440
- return this.agentReputation.getCreditScore(this.agentId);
503
+ return this.agether8004Scorer.getCreditScore(this.agentId);
441
504
  }
442
505
  async isScoreFresh() {
443
- const [fresh, age] = await this.agentReputation.isScoreFresh(this.agentId);
506
+ const [fresh, age] = await this.agether8004Scorer.isScoreFresh(this.agentId);
444
507
  return { fresh, age };
445
508
  }
446
509
  async isEligible(minScore = 500n) {
447
- const [eligible, currentScore] = await this.agentReputation.isEligible(this.agentId, minScore);
510
+ const [eligible, currentScore] = await this.agether8004Scorer.isEligible(this.agentId, minScore);
448
511
  return { eligible, currentScore };
449
512
  }
450
513
  // Getters
@@ -509,27 +572,24 @@ var MorphoClient = class {
509
572
  this._eoaAddress = wallet.address;
510
573
  }
511
574
  const addrs = { ...defaultCfg.contracts, ...config.contracts };
512
- this.accountFactory = new import_ethers2.Contract(addrs.accountFactory, ACCOUNT_FACTORY_ABI, this._signer);
575
+ this.agether4337Factory = new import_ethers2.Contract(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
513
576
  this.morphoBlue = new import_ethers2.Contract(addrs.morphoBlue, MORPHO_BLUE_ABI, this.provider);
514
- this.agentReputation = new import_ethers2.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
577
+ this.agether8004Scorer = new import_ethers2.Contract(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
515
578
  this.identityRegistry = new import_ethers2.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
579
+ this.entryPoint = new import_ethers2.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
580
+ this.validationModule = new import_ethers2.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
516
581
  }
517
582
  // ════════════════════════════════════════════════════════
518
583
  // KYA Gate Check
519
584
  // ════════════════════════════════════════════════════════
520
585
  /**
521
586
  * Check whether the KYA (Know Your Agent) code verification gate is active.
522
- * Reads the account's installed hook and checks if it has a non-zero
523
- * validationRegistry when set, the hook enforces KYA code approval.
587
+ * Reads the ERC8004ValidationModule's validationRegistry when set to
588
+ * a non-zero address, the module enforces KYA code approval.
524
589
  */
525
590
  async isKyaRequired() {
526
591
  try {
527
- const acctAddr = await this.getAccountAddress();
528
- const account = new import_ethers2.Contract(acctAddr, AGENT_ACCOUNT_ABI, this.provider);
529
- const hookAddr = await account.hook();
530
- if (hookAddr === import_ethers2.ethers.ZeroAddress) return false;
531
- const hook = new import_ethers2.Contract(hookAddr, KYA_HOOK_ABI, this.provider);
532
- const registryAddr = await hook.validationRegistry();
592
+ const registryAddr = await this.validationModule.validationRegistry();
533
593
  return registryAddr !== import_ethers2.ethers.ZeroAddress;
534
594
  } catch {
535
595
  return false;
@@ -546,7 +606,7 @@ var MorphoClient = class {
546
606
  let lastErr;
547
607
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
548
608
  try {
549
- const addr = await this.accountFactory.getAccount(BigInt(this.agentId));
609
+ const addr = await this.agether4337Factory.getAccount(BigInt(this.agentId));
550
610
  if (addr === import_ethers2.ethers.ZeroAddress) {
551
611
  throw new AgetherError("No AgentAccount found. Call register() first.", "NO_ACCOUNT");
552
612
  }
@@ -624,9 +684,9 @@ var MorphoClient = class {
624
684
  async register(_name) {
625
685
  const eoaAddr = await this.getSignerAddress();
626
686
  if (this.agentId) {
627
- const exists = await this.accountFactory.accountExists(BigInt(this.agentId));
687
+ const exists = await this.agether4337Factory.accountExists(BigInt(this.agentId));
628
688
  if (exists) {
629
- const acct = await this.accountFactory.getAccount(BigInt(this.agentId));
689
+ const acct = await this.agether4337Factory.getAccount(BigInt(this.agentId));
630
690
  this._accountAddress = acct;
631
691
  const kyaRequired2 = await this.isKyaRequired();
632
692
  return { agentId: this.agentId, address: eoaAddr, agentAccount: acct, alreadyRegistered: true, kyaRequired: kyaRequired2 };
@@ -644,15 +704,15 @@ var MorphoClient = class {
644
704
  agentId = await this._mintNewIdentity();
645
705
  }
646
706
  this.agentId = agentId.toString();
647
- const acctExists = await this.accountFactory.accountExists(agentId);
707
+ const acctExists = await this.agether4337Factory.accountExists(agentId);
648
708
  let txHash;
649
709
  if (!acctExists) {
650
- const tx = await this.accountFactory.createAccount(agentId);
710
+ const tx = await this.agether4337Factory.createAccount(agentId);
651
711
  const receipt = await tx.wait();
652
712
  this._refreshSigner();
653
713
  txHash = receipt.hash;
654
714
  }
655
- const acctAddr = await this.accountFactory.getAccount(agentId);
715
+ const acctAddr = await this.agether4337Factory.getAccount(agentId);
656
716
  this._accountAddress = acctAddr;
657
717
  const kyaRequired = await this.isKyaRequired();
658
718
  return {
@@ -796,7 +856,7 @@ var MorphoClient = class {
796
856
  }
797
857
  /**
798
858
  * Get MarketParams for a collateral token.
799
- * Tries cache → API → on-chain idToMarketParams.
859
+ * Tries cache → API → onchain idToMarketParams.
800
860
  */
801
861
  async findMarketForCollateral(collateralSymbolOrAddress) {
802
862
  const colInfo = BASE_COLLATERALS[collateralSymbolOrAddress];
@@ -811,7 +871,7 @@ var MorphoClient = class {
811
871
  "MARKET_NOT_FOUND"
812
872
  );
813
873
  }
814
- /** Read MarketParams on-chain by market ID (bytes32). */
874
+ /** Read MarketParams onchain by market ID (bytes32). */
815
875
  async getMarketParams(marketId) {
816
876
  const result = await this.morphoBlue.idToMarketParams(marketId);
817
877
  return {
@@ -825,7 +885,7 @@ var MorphoClient = class {
825
885
  // ════════════════════════════════════════════════════════
826
886
  // Position Reads
827
887
  // ════════════════════════════════════════════════════════
828
- /** Read on-chain position for a specific market. */
888
+ /** Read onchain position for a specific market. */
829
889
  async getPosition(marketId) {
830
890
  const acctAddr = await this.getAccountAddress();
831
891
  const pos = await this.morphoBlue.position(marketId, acctAddr);
@@ -1379,7 +1439,7 @@ var MorphoClient = class {
1379
1439
  if (target.address) {
1380
1440
  targetAddr = target.address;
1381
1441
  } else if (target.agentId) {
1382
- targetAddr = await this.accountFactory.getAccount(BigInt(target.agentId));
1442
+ targetAddr = await this.agether4337Factory.getAccount(BigInt(target.agentId));
1383
1443
  if (targetAddr === import_ethers2.ethers.ZeroAddress) throw new AgetherError("Target agent has no account", "NO_ACCOUNT");
1384
1444
  } else {
1385
1445
  throw new AgetherError("Provide agentId or address", "INVALID_TARGET");
@@ -1392,25 +1452,25 @@ var MorphoClient = class {
1392
1452
  return { tx: receipt.hash, targetAccount: targetAddr, targetAgentId: target.agentId };
1393
1453
  }
1394
1454
  // ════════════════════════════════════════════════════════
1395
- // Reputation (AgentReputation contract)
1455
+ // Reputation (Agether8004Scorer contract)
1396
1456
  // ════════════════════════════════════════════════════════
1397
1457
  async getCreditScore() {
1398
1458
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1399
- return this.agentReputation.getCreditScore(BigInt(this.agentId));
1459
+ return this.agether8004Scorer.getCreditScore(BigInt(this.agentId));
1400
1460
  }
1401
1461
  async getAttestation() {
1402
1462
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1403
- const att = await this.agentReputation.getAttestation(BigInt(this.agentId));
1463
+ const att = await this.agether8004Scorer.getAttestation(BigInt(this.agentId));
1404
1464
  return { score: att.score, timestamp: att.timestamp, signer: att.signer };
1405
1465
  }
1406
1466
  async isEligible(minScore = 500n) {
1407
1467
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1408
- const [eligible, currentScore] = await this.agentReputation.isEligible(BigInt(this.agentId), minScore);
1468
+ const [eligible, currentScore] = await this.agether8004Scorer.isEligible(BigInt(this.agentId), minScore);
1409
1469
  return { eligible, currentScore };
1410
1470
  }
1411
1471
  async isScoreFresh() {
1412
1472
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1413
- const [fresh, age] = await this.agentReputation.isScoreFresh(BigInt(this.agentId));
1473
+ const [fresh, age] = await this.agether8004Scorer.isScoreFresh(BigInt(this.agentId));
1414
1474
  return { fresh, age };
1415
1475
  }
1416
1476
  // ════════════════════════════════════════════════════════
@@ -1432,8 +1492,10 @@ var MorphoClient = class {
1432
1492
  _refreshSigner() {
1433
1493
  if (this._useExternalSigner) {
1434
1494
  const addrs = this.config.contracts;
1435
- this.accountFactory = new import_ethers2.Contract(addrs.accountFactory, ACCOUNT_FACTORY_ABI, this._signer);
1436
- this.agentReputation = new import_ethers2.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
1495
+ this.agether4337Factory = new import_ethers2.Contract(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
1496
+ this.entryPoint = new import_ethers2.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
1497
+ this.validationModule = new import_ethers2.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
1498
+ this.agether8004Scorer = new import_ethers2.Contract(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
1437
1499
  this.identityRegistry = new import_ethers2.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
1438
1500
  } else {
1439
1501
  this.provider = new import_ethers2.ethers.JsonRpcProvider(this._rpcUrl);
@@ -1441,57 +1503,87 @@ var MorphoClient = class {
1441
1503
  this._signer = wallet;
1442
1504
  this._eoaAddress = wallet.address;
1443
1505
  const addrs = this.config.contracts;
1444
- this.accountFactory = new import_ethers2.Contract(addrs.accountFactory, ACCOUNT_FACTORY_ABI, this._signer);
1445
- this.agentReputation = new import_ethers2.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
1506
+ this.agether4337Factory = new import_ethers2.Contract(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
1507
+ this.entryPoint = new import_ethers2.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
1508
+ this.validationModule = new import_ethers2.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
1509
+ this.agether8004Scorer = new import_ethers2.Contract(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
1446
1510
  this.identityRegistry = new import_ethers2.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
1447
1511
  }
1448
1512
  }
1513
+ // ────────────────────────────────────────────────────────────
1514
+ // ERC-4337 UserOp helpers (Safe + Safe7579 + EntryPoint v0.7)
1515
+ // ────────────────────────────────────────────────────────────
1449
1516
  /**
1450
- * Execute a single call via AgentAccount.execute (ERC-7579 single mode).
1517
+ * Pack two uint128 values into a single bytes32:
1518
+ * bytes32 = (hi << 128) | lo
1519
+ */
1520
+ _packUint128(hi, lo) {
1521
+ return import_ethers2.ethers.zeroPadValue(import_ethers2.ethers.toBeHex(hi << 128n | lo), 32);
1522
+ }
1523
+ /**
1524
+ * Build, sign and submit a PackedUserOperation through EntryPoint.handleOps.
1525
+ *
1526
+ * @param callData – the ABI-encoded calldata for the Safe7579 account
1527
+ * (e.g. `execute(mode, executionCalldata)`)
1528
+ * @returns the transaction receipt of the handleOps call
1529
+ */
1530
+ async _submitUserOp(callData) {
1531
+ const sender = await this.getAccountAddress();
1532
+ const nonce = await this.entryPoint.getNonce(sender, 0);
1533
+ const feeData = await this.provider.getFeeData();
1534
+ const maxFeePerGas = feeData.maxFeePerGas ?? import_ethers2.ethers.parseUnits("0.5", "gwei");
1535
+ const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? import_ethers2.ethers.parseUnits("0.1", "gwei");
1536
+ const verificationGasLimit = 500000n;
1537
+ const callGasLimit = 800000n;
1538
+ const preVerificationGas = 100000n;
1539
+ const accountGasLimits = this._packUint128(verificationGasLimit, callGasLimit);
1540
+ const gasFees = this._packUint128(maxPriorityFeePerGas, maxFeePerGas);
1541
+ const userOp = {
1542
+ sender,
1543
+ nonce,
1544
+ initCode: "0x",
1545
+ callData,
1546
+ accountGasLimits,
1547
+ preVerificationGas,
1548
+ gasFees,
1549
+ paymasterAndData: "0x",
1550
+ signature: "0x"
1551
+ // placeholder — replaced after signing
1552
+ };
1553
+ const userOpHash = await this.entryPoint.getUserOpHash(userOp);
1554
+ const signature = await this._signer.signMessage(import_ethers2.ethers.getBytes(userOpHash));
1555
+ userOp.signature = signature;
1556
+ const tx = await this.entryPoint.handleOps([userOp], await this.getSignerAddress());
1557
+ const receipt = await tx.wait();
1558
+ this._refreshSigner();
1559
+ return receipt;
1560
+ }
1561
+ /**
1562
+ * Execute a single call via Safe7579 account (ERC-7579 single mode)
1563
+ * through an ERC-4337 UserOperation.
1451
1564
  */
1452
1565
  async exec(target, data, value = 0n) {
1453
- const acctAddr = await this.getAccountAddress();
1454
- const account = new import_ethers2.Contract(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1455
1566
  const executionCalldata = import_ethers2.ethers.AbiCoder.defaultAbiCoder().encode(
1456
1567
  ["address", "uint256", "bytes"],
1457
1568
  [target, value, data]
1458
1569
  );
1459
- let gasLimit;
1460
- try {
1461
- const estimate = await account.execute.estimateGas(MODE_SINGLE, executionCalldata);
1462
- gasLimit = estimate * 130n / 100n;
1463
- } catch (e) {
1464
- console.warn("[agether] exec gas estimation failed, using default 500k:", e instanceof Error ? e.message : e);
1465
- gasLimit = 500000n;
1466
- }
1467
- const tx = await account.execute(MODE_SINGLE, executionCalldata, { gasLimit });
1468
- const receipt = await tx.wait();
1469
- this._refreshSigner();
1470
- return receipt;
1570
+ const safe7579Iface = new import_ethers2.ethers.Interface(SAFE7579_ACCOUNT_ABI);
1571
+ const callData = safe7579Iface.encodeFunctionData("execute", [MODE_SINGLE, executionCalldata]);
1572
+ return this._submitUserOp(callData);
1471
1573
  }
1472
1574
  /**
1473
- * Execute multiple calls via AgentAccount.execute (ERC-7579 batch mode).
1575
+ * Execute multiple calls via Safe7579 account (ERC-7579 batch mode)
1576
+ * through an ERC-4337 UserOperation.
1474
1577
  */
1475
1578
  async batch(targets, values, datas) {
1476
- const acctAddr = await this.getAccountAddress();
1477
- const account = new import_ethers2.Contract(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1478
1579
  const executions = targets.map((t, i) => [t, values[i], datas[i]]);
1479
1580
  const executionCalldata = import_ethers2.ethers.AbiCoder.defaultAbiCoder().encode(
1480
1581
  ["(address,uint256,bytes)[]"],
1481
1582
  [executions]
1482
1583
  );
1483
- let gasLimit;
1484
- try {
1485
- const estimate = await account.execute.estimateGas(MODE_BATCH, executionCalldata);
1486
- gasLimit = estimate * 130n / 100n;
1487
- } catch (e) {
1488
- console.warn("[agether] batch gas estimation failed, using default 800k:", e instanceof Error ? e.message : e);
1489
- gasLimit = 800000n;
1490
- }
1491
- const tx = await account.execute(MODE_BATCH, executionCalldata, { gasLimit });
1492
- const receipt = await tx.wait();
1493
- this._refreshSigner();
1494
- return receipt;
1584
+ const safe7579Iface = new import_ethers2.ethers.Interface(SAFE7579_ACCOUNT_ABI);
1585
+ const callData = safe7579Iface.encodeFunctionData("execute", [MODE_BATCH, executionCalldata]);
1586
+ return this._submitUserOp(callData);
1495
1587
  }
1496
1588
  /** Convert MorphoMarketParams to Solidity tuple. */
1497
1589
  _toTuple(p) {
@@ -1858,14 +1950,14 @@ var ScoringClient = class {
1858
1950
  }
1859
1951
  }
1860
1952
  // ════════════════════════════════════════════════════════
1861
- // Score (x402-gated — computes & submits on-chain)
1953
+ // Score (x402-gated — computes & submits onchain)
1862
1954
  // ════════════════════════════════════════════════════════
1863
1955
  /**
1864
1956
  * Request a fresh score computation.
1865
1957
  *
1866
1958
  * This is x402-gated: the backend returns 402, the X402Client
1867
1959
  * signs an EIP-3009 payment, and the backend computes + submits
1868
- * the score on-chain via AgentReputation.submitScore().
1960
+ * the score onchain via AgentReputation.submitScore().
1869
1961
  *
1870
1962
  * Returns the ScoreResult with breakdown and txHash.
1871
1963
  */
@@ -1889,10 +1981,10 @@ var ScoringClient = class {
1889
1981
  return result.data;
1890
1982
  }
1891
1983
  // ════════════════════════════════════════════════════════
1892
- // Current Score (free — reads on-chain)
1984
+ // Current Score (free — reads onchain)
1893
1985
  // ════════════════════════════════════════════════════════
1894
1986
  /**
1895
- * Get the current on-chain score (free, no payment required).
1987
+ * Get the current onchain score (free, no payment required).
1896
1988
  */
1897
1989
  async getCurrentScore(agentId) {
1898
1990
  const response = await this.client.get(`/score/${agentId.toString()}/current`);
@@ -2041,7 +2133,7 @@ var AgentIdentityClient = class {
2041
2133
  return { ...result, existing: false };
2042
2134
  }
2043
2135
  /**
2044
- * Register agent with URI and on-chain metadata
2136
+ * Register agent with URI and onchain metadata
2045
2137
  */
2046
2138
  async registerWithMetadata(agentURI, metadata) {
2047
2139
  const metadataEntries = metadata.map((m) => ({
@@ -2077,7 +2169,7 @@ var AgentIdentityClient = class {
2077
2169
  return receipt.hash;
2078
2170
  }
2079
2171
  /**
2080
- * Set on-chain metadata (key-value)
2172
+ * Set onchain metadata (key-value)
2081
2173
  */
2082
2174
  async setMetadata(agentId, key, value) {
2083
2175
  const tx = await this.identityRegistry.setMetadata(
@@ -2089,7 +2181,7 @@ var AgentIdentityClient = class {
2089
2181
  return receipt.hash;
2090
2182
  }
2091
2183
  /**
2092
- * Get on-chain metadata
2184
+ * Get onchain metadata
2093
2185
  */
2094
2186
  async getMetadata(agentId, key) {
2095
2187
  const value = await this.identityRegistry.getMetadata(agentId, key);
@@ -2318,19 +2410,26 @@ function rateToBps(rate) {
2318
2410
  // Annotate the CommonJS export names for ESM import in node:
2319
2411
  0 && (module.exports = {
2320
2412
  ACCOUNT_FACTORY_ABI,
2321
- AGENT_ACCOUNT_ABI,
2322
2413
  AGENT_REPUTATION_ABI,
2414
+ AGETHER_4337_FACTORY_ABI,
2415
+ AGETHER_8004_SCORER_ABI,
2416
+ AGETHER_8004_VALIDATION_MODULE_ABI,
2417
+ AGETHER_HOOK_MULTIPLEXER_ABI,
2323
2418
  AgentIdentityClient,
2324
2419
  AgentNotApprovedError,
2325
2420
  AgetherClient,
2326
2421
  AgetherError,
2327
2422
  ChainId,
2423
+ ENTRYPOINT_V07_ABI,
2328
2424
  ERC20_ABI,
2425
+ ERC8004_VALIDATION_MODULE_ABI,
2426
+ HOOK_MULTIPLEXER_ABI,
2329
2427
  IDENTITY_REGISTRY_ABI,
2330
2428
  InsufficientBalanceError,
2331
- KYA_HOOK_ABI,
2332
2429
  MORPHO_BLUE_ABI,
2333
2430
  MorphoClient,
2431
+ SAFE7579_ACCOUNT_ABI,
2432
+ SAFE_AGENT_FACTORY_ABI,
2334
2433
  ScoringClient,
2335
2434
  ScoringRejectedError,
2336
2435
  VALIDATION_REGISTRY_ABI,