@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/README.md CHANGED
@@ -528,7 +528,7 @@ $ agether apply --limit 5000
528
528
  ⚠️ You will need to deposit collateral before drawing funds.
529
529
  After approval, run: agether collateral --amount 4000
530
530
 
531
- [2/2] Submitting application on-chain...
531
+ [2/2] Submitting application onchain...
532
532
  ✓ TX: 0x...
533
533
 
534
534
  ✅ Credit Line #1 created (Pending)
package/dist/cli.js CHANGED
@@ -47,7 +47,7 @@ var init_types = __esm({
47
47
  });
48
48
 
49
49
  // src/utils/abis.ts
50
- var IDENTITY_REGISTRY_ABI, ACCOUNT_FACTORY_ABI, AGENT_ACCOUNT_ABI, AGENT_REPUTATION_ABI, MORPHO_BLUE_ABI, ERC20_ABI, KYA_HOOK_ABI;
50
+ var IDENTITY_REGISTRY_ABI, AGETHER_4337_FACTORY_ABI, ACCOUNT_FACTORY_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, ERC8004_VALIDATION_MODULE_ABI, AGETHER_8004_SCORER_ABI, AGENT_REPUTATION_ABI, MORPHO_BLUE_ABI, ERC20_ABI, ENTRYPOINT_V07_ABI, SAFE7579_ACCOUNT_ABI;
51
51
  var init_abis = __esm({
52
52
  "src/utils/abis.ts"() {
53
53
  "use strict";
@@ -59,40 +59,36 @@ var init_abis = __esm({
59
59
  "function register() returns (uint256 agentId)",
60
60
  "event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)"
61
61
  ];
62
- ACCOUNT_FACTORY_ABI = [
62
+ AGETHER_4337_FACTORY_ABI = [
63
63
  "function getAccount(uint256 agentId) view returns (address)",
64
64
  "function accountExists(uint256 agentId) view returns (bool)",
65
- "function predictAddress(uint256 agentId) view returns (address)",
66
65
  "function totalAccounts() view returns (uint256)",
67
66
  "function getAgentId(address account) view returns (uint256)",
68
- "function createAccount(uint256 agentId) returns (address account)",
69
- "function protocolHook() view returns (address)",
67
+ "function getAgentIdByIndex(uint256 index) view returns (uint256)",
68
+ "function getAllAgentIds() view returns (uint256[])",
69
+ "function createAccount(uint256 agentId) returns (address safeAccount)",
70
70
  "function identityRegistry() view returns (address)",
71
- "event AccountCreated(uint256 indexed agentId, address indexed account, address indexed owner)"
71
+ "function validationModule() view returns (address)",
72
+ "function hookMultiplexer() view returns (address)",
73
+ "function safeSingleton() view returns (address)",
74
+ "function safe7579() view returns (address)",
75
+ "function bootstrap() view returns (address)",
76
+ "event AccountCreated(uint256 indexed agentId, address indexed safeAccount, address indexed owner)"
72
77
  ];
73
- AGENT_ACCOUNT_ABI = [
74
- "function agentId() view returns (uint256)",
78
+ ACCOUNT_FACTORY_ABI = AGETHER_4337_FACTORY_ABI;
79
+ AGETHER_8004_VALIDATION_MODULE_ABI = [
80
+ // View
81
+ "function getConfig(address account) view returns (address registry, uint256 agentId)",
82
+ "function getOwner(address account) view returns (address)",
83
+ "function isInstalled(address account) view returns (bool)",
84
+ "function isKYAApproved(address account) view returns (bool)",
85
+ "function validationRegistry() view returns (address)",
75
86
  "function owner() view returns (address)",
76
- "function factory() view returns (address)",
77
- "function identityRegistry() view returns (address)",
78
- "function balanceOf(address token) view returns (uint256)",
79
- "function ethBalance() view returns (uint256)",
80
- // ERC-7579 execution
81
- "function execute(bytes32 mode, bytes executionCalldata) payable",
82
- "function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
83
- // ERC-7579 module management
84
- "function installModule(uint256 moduleTypeId, address module, bytes initData) payable",
85
- "function uninstallModule(uint256 moduleTypeId, address module, bytes deInitData) payable",
86
- "function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
87
- "function hook() view returns (address)",
88
- // Funding (direct, no execution needed)
89
- "function fund(address token, uint256 amount)",
90
- "function withdraw(address token, uint256 amount, address to)",
91
- "function withdrawETH(uint256 amount, address to)",
92
- // EIP-1271
93
- "function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
87
+ // Admin (via TimelockController)
88
+ "function setValidationRegistry(address registry_)"
94
89
  ];
95
- AGENT_REPUTATION_ABI = [
90
+ ERC8004_VALIDATION_MODULE_ABI = AGETHER_8004_VALIDATION_MODULE_ABI;
91
+ AGETHER_8004_SCORER_ABI = [
96
92
  "function getCreditScore(uint256 agentId) view returns (uint256)",
97
93
  "function getAttestation(uint256 agentId) view returns (tuple(uint256 score, uint256 timestamp, address signer))",
98
94
  "function isScoreFresh(uint256 agentId) view returns (bool fresh, uint256 age)",
@@ -102,6 +98,7 @@ var init_abis = __esm({
102
98
  "function setOracleSigner(address signer_)",
103
99
  "event ScoreUpdated(uint256 indexed agentId, uint256 score, uint256 timestamp, address signer)"
104
100
  ];
101
+ AGENT_REPUTATION_ABI = AGETHER_8004_SCORER_ABI;
105
102
  MORPHO_BLUE_ABI = [
106
103
  // Supply & Withdraw (lending side)
107
104
  "function supply(tuple(address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) marketParams, uint256 assets, uint256 shares, address onBehalf, bytes data) returns (uint256 assetsSupplied, uint256 sharesSupplied)",
@@ -130,9 +127,22 @@ var init_abis = __esm({
130
127
  "function symbol() view returns (string)",
131
128
  "function name() view returns (string)"
132
129
  ];
133
- KYA_HOOK_ABI = [
134
- "function validationRegistry() view returns (address)",
135
- "function setValidationRegistry(address newRegistry)"
130
+ ENTRYPOINT_V07_ABI = [
131
+ "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)",
132
+ "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)",
133
+ "function getNonce(address sender, uint192 key) view returns (uint256 nonce)",
134
+ "function balanceOf(address account) view returns (uint256)",
135
+ "function depositTo(address account) payable",
136
+ "event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed)"
137
+ ];
138
+ SAFE7579_ACCOUNT_ABI = [
139
+ // ERC-7579 execution (called via UserOp through Safe7579 fallback)
140
+ "function execute(bytes32 mode, bytes executionCalldata) payable",
141
+ "function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
142
+ // ERC-7579 module queries
143
+ "function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
144
+ // EIP-1271
145
+ "function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
136
146
  ];
137
147
  }
138
148
  });
@@ -146,56 +156,99 @@ function getDefaultConfig(chainId) {
146
156
  scoringEndpoint: SCORING_ENDPOINTS[chainId]
147
157
  };
148
158
  }
149
- var CONTRACT_ADDRESSES, RPC_URLS, SCORING_ENDPOINTS;
159
+ var ZERO, ENTRYPOINT_V07, ERC8004_IDENTITY_REGISTRY, ERC8004_IDENTITY_REGISTRY_TESTNET, MORPHO_BLUE, SAFE_SINGLETON, SAFE_PROXY_FACTORY, SAFE7579, CONTRACT_ADDRESSES, RPC_URLS, SCORING_ENDPOINTS;
150
160
  var init_config = __esm({
151
161
  "src/utils/config.ts"() {
152
162
  "use strict";
153
163
  init_types();
164
+ ZERO = "0x0000000000000000000000000000000000000000";
165
+ ENTRYPOINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
166
+ ERC8004_IDENTITY_REGISTRY = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
167
+ ERC8004_IDENTITY_REGISTRY_TESTNET = "0x8004A818BFB912233c491871b3d84c89A494BD9e";
168
+ MORPHO_BLUE = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
169
+ SAFE_SINGLETON = "0x41675C099F32341bf84BFc5382aF534df5C7461a";
170
+ SAFE_PROXY_FACTORY = "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67";
171
+ SAFE7579 = "0x7579EE8307284F293B1927136486880611F20002";
154
172
  CONTRACT_ADDRESSES = {
155
173
  [1 /* Ethereum */]: {
156
- accountFactory: "0x0000000000000000000000000000000000000000",
157
- validationRegistry: "0x0000000000000000000000000000000000000000",
158
- agentReputation: "0x0000000000000000000000000000000000000000",
159
- kyaHook: "0x0000000000000000000000000000000000000000",
174
+ safeSingleton: SAFE_SINGLETON,
175
+ safeProxyFactory: SAFE_PROXY_FACTORY,
176
+ safe7579: SAFE7579,
177
+ entryPoint: ENTRYPOINT_V07,
178
+ agether4337Factory: ZERO,
179
+ agether7579Bootstrap: ZERO,
180
+ erc8004ValidationModule: ZERO,
181
+ agetherHookMultiplexer: ZERO,
182
+ validationRegistry: ZERO,
183
+ agether8004Scorer: ZERO,
184
+ timelockController: ZERO,
160
185
  usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
161
- identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
162
- morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
186
+ identityRegistry: ERC8004_IDENTITY_REGISTRY,
187
+ morphoBlue: MORPHO_BLUE
163
188
  },
164
189
  [8453 /* Base */]: {
165
- accountFactory: "0x89a8758E60A56EcB47247D92E05447eFd450d6Bf",
166
- validationRegistry: "0x6f76cF69B71Dc5F9A414BCEe4583b12738E47985",
167
- agentReputation: "0xe88f3419a2dbac70e3aF6E487b0C63e8301C6A87",
168
- kyaHook: "0x28e50Aa9eD517E369b2806928709B44062aD9821",
190
+ safeSingleton: SAFE_SINGLETON,
191
+ safeProxyFactory: SAFE_PROXY_FACTORY,
192
+ safe7579: SAFE7579,
193
+ entryPoint: ENTRYPOINT_V07,
194
+ agether4337Factory: "0x7B23470dCD65b8fEA3Bf49466860b3A55D56268C",
195
+ agether7579Bootstrap: "0x62d34D22D379367EEDcb7D1E4dE899A654E982D0",
196
+ erc8004ValidationModule: "0xfC6ccFd12e163460C7Ef92d38DC0be6C6cA10f6C",
197
+ agetherHookMultiplexer: "0x094FE93a8b733a97a6945530cA83058CaCbf5278",
198
+ validationRegistry: ZERO,
199
+ agether8004Scorer: "0x9f0084E5c941365149c8953133cF062E33a19b8d",
200
+ timelockController: "0x2807912DA2a7278AF883a376bE15bBBf3ab99f52",
169
201
  usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
170
- identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
171
- morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
202
+ identityRegistry: ERC8004_IDENTITY_REGISTRY,
203
+ morphoBlue: MORPHO_BLUE
172
204
  },
173
205
  [84532 /* BaseSepolia */]: {
174
- accountFactory: "0x0000000000000000000000000000000000000000",
175
- validationRegistry: "0x0000000000000000000000000000000000000000",
176
- agentReputation: "0x0000000000000000000000000000000000000000",
177
- kyaHook: "0x0000000000000000000000000000000000000000",
206
+ safeSingleton: SAFE_SINGLETON,
207
+ safeProxyFactory: SAFE_PROXY_FACTORY,
208
+ safe7579: SAFE7579,
209
+ entryPoint: ENTRYPOINT_V07,
210
+ agether4337Factory: ZERO,
211
+ agether7579Bootstrap: ZERO,
212
+ erc8004ValidationModule: ZERO,
213
+ agetherHookMultiplexer: ZERO,
214
+ validationRegistry: ZERO,
215
+ agether8004Scorer: ZERO,
216
+ timelockController: ZERO,
178
217
  usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
179
- identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
180
- morphoBlue: "0x0000000000000000000000000000000000000000"
218
+ identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
219
+ morphoBlue: ZERO
181
220
  },
182
221
  [11155111 /* Sepolia */]: {
183
- accountFactory: "0x0000000000000000000000000000000000000000",
184
- validationRegistry: "0x0000000000000000000000000000000000000000",
185
- agentReputation: "0x0000000000000000000000000000000000000000",
186
- kyaHook: "0x0000000000000000000000000000000000000000",
222
+ safeSingleton: SAFE_SINGLETON,
223
+ safeProxyFactory: SAFE_PROXY_FACTORY,
224
+ safe7579: SAFE7579,
225
+ entryPoint: ENTRYPOINT_V07,
226
+ agether4337Factory: ZERO,
227
+ agether7579Bootstrap: ZERO,
228
+ erc8004ValidationModule: ZERO,
229
+ agetherHookMultiplexer: ZERO,
230
+ validationRegistry: ZERO,
231
+ agether8004Scorer: ZERO,
232
+ timelockController: ZERO,
187
233
  usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
188
- identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
189
- morphoBlue: "0x0000000000000000000000000000000000000000"
234
+ identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
235
+ morphoBlue: ZERO
190
236
  },
191
237
  [31337 /* Hardhat */]: {
192
- accountFactory: "0x0000000000000000000000000000000000000000",
193
- validationRegistry: "0x0000000000000000000000000000000000000000",
194
- agentReputation: "0x0000000000000000000000000000000000000000",
195
- kyaHook: "0x0000000000000000000000000000000000000000",
238
+ safeSingleton: SAFE_SINGLETON,
239
+ safeProxyFactory: SAFE_PROXY_FACTORY,
240
+ safe7579: SAFE7579,
241
+ entryPoint: ENTRYPOINT_V07,
242
+ agether4337Factory: ZERO,
243
+ agether7579Bootstrap: ZERO,
244
+ erc8004ValidationModule: ZERO,
245
+ agetherHookMultiplexer: ZERO,
246
+ validationRegistry: ZERO,
247
+ agether8004Scorer: ZERO,
248
+ timelockController: ZERO,
196
249
  usdc: "0x56d4d6aEe0278c5Df2FA23Ecb32eC146C9446FDf",
197
- identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
198
- morphoBlue: "0x0000000000000000000000000000000000000000"
250
+ identityRegistry: ERC8004_IDENTITY_REGISTRY,
251
+ morphoBlue: ZERO
199
252
  }
200
253
  };
201
254
  RPC_URLS = {
@@ -270,27 +323,24 @@ var init_MorphoClient = __esm({
270
323
  this._eoaAddress = wallet.address;
271
324
  }
272
325
  const addrs = { ...defaultCfg.contracts, ...config.contracts };
273
- this.accountFactory = new import_ethers.Contract(addrs.accountFactory, ACCOUNT_FACTORY_ABI, this._signer);
326
+ this.agether4337Factory = new import_ethers.Contract(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
274
327
  this.morphoBlue = new import_ethers.Contract(addrs.morphoBlue, MORPHO_BLUE_ABI, this.provider);
275
- this.agentReputation = new import_ethers.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
328
+ this.agether8004Scorer = new import_ethers.Contract(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
276
329
  this.identityRegistry = new import_ethers.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
330
+ this.entryPoint = new import_ethers.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
331
+ this.validationModule = new import_ethers.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
277
332
  }
278
333
  // ════════════════════════════════════════════════════════
279
334
  // KYA Gate Check
280
335
  // ════════════════════════════════════════════════════════
281
336
  /**
282
337
  * Check whether the KYA (Know Your Agent) code verification gate is active.
283
- * Reads the account's installed hook and checks if it has a non-zero
284
- * validationRegistry when set, the hook enforces KYA code approval.
338
+ * Reads the ERC8004ValidationModule's validationRegistry when set to
339
+ * a non-zero address, the module enforces KYA code approval.
285
340
  */
286
341
  async isKyaRequired() {
287
342
  try {
288
- const acctAddr = await this.getAccountAddress();
289
- const account = new import_ethers.Contract(acctAddr, AGENT_ACCOUNT_ABI, this.provider);
290
- const hookAddr = await account.hook();
291
- if (hookAddr === import_ethers.ethers.ZeroAddress) return false;
292
- const hook = new import_ethers.Contract(hookAddr, KYA_HOOK_ABI, this.provider);
293
- const registryAddr = await hook.validationRegistry();
343
+ const registryAddr = await this.validationModule.validationRegistry();
294
344
  return registryAddr !== import_ethers.ethers.ZeroAddress;
295
345
  } catch {
296
346
  return false;
@@ -307,7 +357,7 @@ var init_MorphoClient = __esm({
307
357
  let lastErr;
308
358
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
309
359
  try {
310
- const addr = await this.accountFactory.getAccount(BigInt(this.agentId));
360
+ const addr = await this.agether4337Factory.getAccount(BigInt(this.agentId));
311
361
  if (addr === import_ethers.ethers.ZeroAddress) {
312
362
  throw new AgetherError("No AgentAccount found. Call register() first.", "NO_ACCOUNT");
313
363
  }
@@ -385,9 +435,9 @@ var init_MorphoClient = __esm({
385
435
  async register(_name) {
386
436
  const eoaAddr = await this.getSignerAddress();
387
437
  if (this.agentId) {
388
- const exists = await this.accountFactory.accountExists(BigInt(this.agentId));
438
+ const exists = await this.agether4337Factory.accountExists(BigInt(this.agentId));
389
439
  if (exists) {
390
- const acct = await this.accountFactory.getAccount(BigInt(this.agentId));
440
+ const acct = await this.agether4337Factory.getAccount(BigInt(this.agentId));
391
441
  this._accountAddress = acct;
392
442
  const kyaRequired2 = await this.isKyaRequired();
393
443
  return { agentId: this.agentId, address: eoaAddr, agentAccount: acct, alreadyRegistered: true, kyaRequired: kyaRequired2 };
@@ -405,15 +455,15 @@ var init_MorphoClient = __esm({
405
455
  agentId = await this._mintNewIdentity();
406
456
  }
407
457
  this.agentId = agentId.toString();
408
- const acctExists = await this.accountFactory.accountExists(agentId);
458
+ const acctExists = await this.agether4337Factory.accountExists(agentId);
409
459
  let txHash;
410
460
  if (!acctExists) {
411
- const tx = await this.accountFactory.createAccount(agentId);
461
+ const tx = await this.agether4337Factory.createAccount(agentId);
412
462
  const receipt = await tx.wait();
413
463
  this._refreshSigner();
414
464
  txHash = receipt.hash;
415
465
  }
416
- const acctAddr = await this.accountFactory.getAccount(agentId);
466
+ const acctAddr = await this.agether4337Factory.getAccount(agentId);
417
467
  this._accountAddress = acctAddr;
418
468
  const kyaRequired = await this.isKyaRequired();
419
469
  return {
@@ -557,7 +607,7 @@ var init_MorphoClient = __esm({
557
607
  }
558
608
  /**
559
609
  * Get MarketParams for a collateral token.
560
- * Tries cache → API → on-chain idToMarketParams.
610
+ * Tries cache → API → onchain idToMarketParams.
561
611
  */
562
612
  async findMarketForCollateral(collateralSymbolOrAddress) {
563
613
  const colInfo = BASE_COLLATERALS[collateralSymbolOrAddress];
@@ -572,7 +622,7 @@ var init_MorphoClient = __esm({
572
622
  "MARKET_NOT_FOUND"
573
623
  );
574
624
  }
575
- /** Read MarketParams on-chain by market ID (bytes32). */
625
+ /** Read MarketParams onchain by market ID (bytes32). */
576
626
  async getMarketParams(marketId) {
577
627
  const result = await this.morphoBlue.idToMarketParams(marketId);
578
628
  return {
@@ -586,7 +636,7 @@ var init_MorphoClient = __esm({
586
636
  // ════════════════════════════════════════════════════════
587
637
  // Position Reads
588
638
  // ════════════════════════════════════════════════════════
589
- /** Read on-chain position for a specific market. */
639
+ /** Read onchain position for a specific market. */
590
640
  async getPosition(marketId) {
591
641
  const acctAddr = await this.getAccountAddress();
592
642
  const pos = await this.morphoBlue.position(marketId, acctAddr);
@@ -1140,7 +1190,7 @@ var init_MorphoClient = __esm({
1140
1190
  if (target.address) {
1141
1191
  targetAddr = target.address;
1142
1192
  } else if (target.agentId) {
1143
- targetAddr = await this.accountFactory.getAccount(BigInt(target.agentId));
1193
+ targetAddr = await this.agether4337Factory.getAccount(BigInt(target.agentId));
1144
1194
  if (targetAddr === import_ethers.ethers.ZeroAddress) throw new AgetherError("Target agent has no account", "NO_ACCOUNT");
1145
1195
  } else {
1146
1196
  throw new AgetherError("Provide agentId or address", "INVALID_TARGET");
@@ -1153,25 +1203,25 @@ var init_MorphoClient = __esm({
1153
1203
  return { tx: receipt.hash, targetAccount: targetAddr, targetAgentId: target.agentId };
1154
1204
  }
1155
1205
  // ════════════════════════════════════════════════════════
1156
- // Reputation (AgentReputation contract)
1206
+ // Reputation (Agether8004Scorer contract)
1157
1207
  // ════════════════════════════════════════════════════════
1158
1208
  async getCreditScore() {
1159
1209
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1160
- return this.agentReputation.getCreditScore(BigInt(this.agentId));
1210
+ return this.agether8004Scorer.getCreditScore(BigInt(this.agentId));
1161
1211
  }
1162
1212
  async getAttestation() {
1163
1213
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1164
- const att = await this.agentReputation.getAttestation(BigInt(this.agentId));
1214
+ const att = await this.agether8004Scorer.getAttestation(BigInt(this.agentId));
1165
1215
  return { score: att.score, timestamp: att.timestamp, signer: att.signer };
1166
1216
  }
1167
1217
  async isEligible(minScore = 500n) {
1168
1218
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1169
- const [eligible, currentScore] = await this.agentReputation.isEligible(BigInt(this.agentId), minScore);
1219
+ const [eligible, currentScore] = await this.agether8004Scorer.isEligible(BigInt(this.agentId), minScore);
1170
1220
  return { eligible, currentScore };
1171
1221
  }
1172
1222
  async isScoreFresh() {
1173
1223
  if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
1174
- const [fresh, age] = await this.agentReputation.isScoreFresh(BigInt(this.agentId));
1224
+ const [fresh, age] = await this.agether8004Scorer.isScoreFresh(BigInt(this.agentId));
1175
1225
  return { fresh, age };
1176
1226
  }
1177
1227
  // ════════════════════════════════════════════════════════
@@ -1193,8 +1243,10 @@ var init_MorphoClient = __esm({
1193
1243
  _refreshSigner() {
1194
1244
  if (this._useExternalSigner) {
1195
1245
  const addrs = this.config.contracts;
1196
- this.accountFactory = new import_ethers.Contract(addrs.accountFactory, ACCOUNT_FACTORY_ABI, this._signer);
1197
- this.agentReputation = new import_ethers.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
1246
+ this.agether4337Factory = new import_ethers.Contract(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
1247
+ this.entryPoint = new import_ethers.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
1248
+ this.validationModule = new import_ethers.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
1249
+ this.agether8004Scorer = new import_ethers.Contract(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
1198
1250
  this.identityRegistry = new import_ethers.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
1199
1251
  } else {
1200
1252
  this.provider = new import_ethers.ethers.JsonRpcProvider(this._rpcUrl);
@@ -1202,57 +1254,87 @@ var init_MorphoClient = __esm({
1202
1254
  this._signer = wallet;
1203
1255
  this._eoaAddress = wallet.address;
1204
1256
  const addrs = this.config.contracts;
1205
- this.accountFactory = new import_ethers.Contract(addrs.accountFactory, ACCOUNT_FACTORY_ABI, this._signer);
1206
- this.agentReputation = new import_ethers.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
1257
+ this.agether4337Factory = new import_ethers.Contract(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
1258
+ this.entryPoint = new import_ethers.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
1259
+ this.validationModule = new import_ethers.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
1260
+ this.agether8004Scorer = new import_ethers.Contract(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
1207
1261
  this.identityRegistry = new import_ethers.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
1208
1262
  }
1209
1263
  }
1264
+ // ────────────────────────────────────────────────────────────
1265
+ // ERC-4337 UserOp helpers (Safe + Safe7579 + EntryPoint v0.7)
1266
+ // ────────────────────────────────────────────────────────────
1210
1267
  /**
1211
- * Execute a single call via AgentAccount.execute (ERC-7579 single mode).
1268
+ * Pack two uint128 values into a single bytes32:
1269
+ * bytes32 = (hi << 128) | lo
1270
+ */
1271
+ _packUint128(hi, lo) {
1272
+ return import_ethers.ethers.zeroPadValue(import_ethers.ethers.toBeHex(hi << 128n | lo), 32);
1273
+ }
1274
+ /**
1275
+ * Build, sign and submit a PackedUserOperation through EntryPoint.handleOps.
1276
+ *
1277
+ * @param callData – the ABI-encoded calldata for the Safe7579 account
1278
+ * (e.g. `execute(mode, executionCalldata)`)
1279
+ * @returns the transaction receipt of the handleOps call
1280
+ */
1281
+ async _submitUserOp(callData) {
1282
+ const sender = await this.getAccountAddress();
1283
+ const nonce = await this.entryPoint.getNonce(sender, 0);
1284
+ const feeData = await this.provider.getFeeData();
1285
+ const maxFeePerGas = feeData.maxFeePerGas ?? import_ethers.ethers.parseUnits("0.5", "gwei");
1286
+ const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? import_ethers.ethers.parseUnits("0.1", "gwei");
1287
+ const verificationGasLimit = 500000n;
1288
+ const callGasLimit = 800000n;
1289
+ const preVerificationGas = 100000n;
1290
+ const accountGasLimits = this._packUint128(verificationGasLimit, callGasLimit);
1291
+ const gasFees = this._packUint128(maxPriorityFeePerGas, maxFeePerGas);
1292
+ const userOp = {
1293
+ sender,
1294
+ nonce,
1295
+ initCode: "0x",
1296
+ callData,
1297
+ accountGasLimits,
1298
+ preVerificationGas,
1299
+ gasFees,
1300
+ paymasterAndData: "0x",
1301
+ signature: "0x"
1302
+ // placeholder — replaced after signing
1303
+ };
1304
+ const userOpHash = await this.entryPoint.getUserOpHash(userOp);
1305
+ const signature = await this._signer.signMessage(import_ethers.ethers.getBytes(userOpHash));
1306
+ userOp.signature = signature;
1307
+ const tx = await this.entryPoint.handleOps([userOp], await this.getSignerAddress());
1308
+ const receipt = await tx.wait();
1309
+ this._refreshSigner();
1310
+ return receipt;
1311
+ }
1312
+ /**
1313
+ * Execute a single call via Safe7579 account (ERC-7579 single mode)
1314
+ * through an ERC-4337 UserOperation.
1212
1315
  */
1213
1316
  async exec(target, data, value = 0n) {
1214
- const acctAddr = await this.getAccountAddress();
1215
- const account = new import_ethers.Contract(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1216
1317
  const executionCalldata = import_ethers.ethers.AbiCoder.defaultAbiCoder().encode(
1217
1318
  ["address", "uint256", "bytes"],
1218
1319
  [target, value, data]
1219
1320
  );
1220
- let gasLimit;
1221
- try {
1222
- const estimate = await account.execute.estimateGas(MODE_SINGLE, executionCalldata);
1223
- gasLimit = estimate * 130n / 100n;
1224
- } catch (e) {
1225
- console.warn("[agether] exec gas estimation failed, using default 500k:", e instanceof Error ? e.message : e);
1226
- gasLimit = 500000n;
1227
- }
1228
- const tx = await account.execute(MODE_SINGLE, executionCalldata, { gasLimit });
1229
- const receipt = await tx.wait();
1230
- this._refreshSigner();
1231
- return receipt;
1321
+ const safe7579Iface = new import_ethers.ethers.Interface(SAFE7579_ACCOUNT_ABI);
1322
+ const callData = safe7579Iface.encodeFunctionData("execute", [MODE_SINGLE, executionCalldata]);
1323
+ return this._submitUserOp(callData);
1232
1324
  }
1233
1325
  /**
1234
- * Execute multiple calls via AgentAccount.execute (ERC-7579 batch mode).
1326
+ * Execute multiple calls via Safe7579 account (ERC-7579 batch mode)
1327
+ * through an ERC-4337 UserOperation.
1235
1328
  */
1236
1329
  async batch(targets, values, datas) {
1237
- const acctAddr = await this.getAccountAddress();
1238
- const account = new import_ethers.Contract(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1239
1330
  const executions = targets.map((t, i) => [t, values[i], datas[i]]);
1240
1331
  const executionCalldata = import_ethers.ethers.AbiCoder.defaultAbiCoder().encode(
1241
1332
  ["(address,uint256,bytes)[]"],
1242
1333
  [executions]
1243
1334
  );
1244
- let gasLimit;
1245
- try {
1246
- const estimate = await account.execute.estimateGas(MODE_BATCH, executionCalldata);
1247
- gasLimit = estimate * 130n / 100n;
1248
- } catch (e) {
1249
- console.warn("[agether] batch gas estimation failed, using default 800k:", e instanceof Error ? e.message : e);
1250
- gasLimit = 800000n;
1251
- }
1252
- const tx = await account.execute(MODE_BATCH, executionCalldata, { gasLimit });
1253
- const receipt = await tx.wait();
1254
- this._refreshSigner();
1255
- return receipt;
1335
+ const safe7579Iface = new import_ethers.ethers.Interface(SAFE7579_ACCOUNT_ABI);
1336
+ const callData = safe7579Iface.encodeFunctionData("execute", [MODE_BATCH, executionCalldata]);
1337
+ return this._submitUserOp(callData);
1256
1338
  }
1257
1339
  /** Convert MorphoMarketParams to Solidity tuple. */
1258
1340
  _toTuple(p) {
@@ -1753,10 +1835,10 @@ async function cmdRegister(name) {
1753
1835
  process.exit(1);
1754
1836
  }
1755
1837
  const registryAddr = contracts.agentRegistry || contracts.identityRegistry;
1756
- const factoryAddr = contracts.accountFactory;
1838
+ const factoryAddr = contracts.agether4337Factory || contracts.safeAgentFactory || contracts.accountFactory;
1757
1839
  const validationAddr = contracts.validationRegistry;
1758
1840
  if (!registryAddr || !factoryAddr) {
1759
- console.error(" \u274C Backend missing agentRegistry or accountFactory");
1841
+ console.error(" \u274C Backend missing agentRegistry or agether4337Factory");
1760
1842
  process.exit(1);
1761
1843
  }
1762
1844
  console.log(" [2/4] Registering on ERC-8004 IdentityRegistry...");
@@ -1773,7 +1855,7 @@ async function cmdRegister(name) {
1773
1855
  process.exit(1);
1774
1856
  }
1775
1857
  } catch {
1776
- console.error(` \u274C agentId ${agentId} does not exist on-chain`);
1858
+ console.error(` \u274C agentId ${agentId} does not exist onchain`);
1777
1859
  process.exit(1);
1778
1860
  }
1779
1861
  } else {
@@ -1839,7 +1921,7 @@ async function cmdRegister(name) {
1839
1921
  } else {
1840
1922
  console.log(" [3/4] Skipping USDC mint (real network)");
1841
1923
  }
1842
- console.log(" [4/4] Creating AgentAccount...");
1924
+ console.log(" [4/4] Creating Safe account...");
1843
1925
  if (factoryAddr) {
1844
1926
  const factory = new import_ethers2.ethers.Contract(factoryAddr, ACCOUNT_FACTORY_ABI2, signer);
1845
1927
  try {
@@ -1934,12 +2016,12 @@ async function cmdScore() {
1934
2016
  try {
1935
2017
  const data = await apiGet(config.backendUrl, `/score/${config.agentId}/current`);
1936
2018
  if (data.score !== void 0) {
1937
- console.log(` On-chain Score: ${data.score}`);
2019
+ console.log(` Onchain Score: ${data.score}`);
1938
2020
  console.log(` Timestamp: ${data.timestamp ? new Date(Number(data.timestamp) * 1e3).toISOString() : "N/A"}`);
1939
2021
  console.log(` Signer: ${data.signer || "N/A"}`);
1940
2022
  console.log(` Fresh: ${data.fresh ? "\u2705" : "\u26A0\uFE0F stale"}`);
1941
2023
  } else {
1942
- console.log(" No score on-chain yet.");
2024
+ console.log(" No score onchain yet.");
1943
2025
  }
1944
2026
  } catch {
1945
2027
  console.log(" Could not fetch current score.");
@@ -2109,14 +2191,14 @@ async function cmdX402Call(url, method = "GET", body) {
2109
2191
  }
2110
2192
  function cmdHelp() {
2111
2193
  console.log(`
2112
- \u{1F3E6} Agether CLI \u2014 Direct Morpho Blue Credit for AI Agents
2194
+ \u{1F3E6} Agether CLI \u2014 Direct Morpho Blue Credit for AI Agents (Safe + Safe7579)
2113
2195
 
2114
2196
  USAGE:
2115
2197
  agether <command> [options]
2116
2198
 
2117
2199
  SETUP:
2118
2200
  init <private-key> [--agent-id <id>] Initialize with private key
2119
- register [--name <n>] Register ERC-8004 + create AgentAccount
2201
+ register [--name <n>] Register ERC-8004 + create Safe account
2120
2202
 
2121
2203
  INFO:
2122
2204
  balance Check ETH + USDC balances
@@ -2132,7 +2214,7 @@ MORPHO LENDING:
2132
2214
  repay --amount <usd> [--token <t>] Repay borrowed USDC
2133
2215
  withdraw --amount <n> --token <t> Withdraw collateral (use 'all' for max)
2134
2216
  sponsor --amount <n> --token <t> --agent-id <id> Send collateral to another agent
2135
- fund --amount <usd> Transfer USDC from EOA to AgentAccount
2217
+ fund --amount <usd> Transfer USDC from EOA to Safe account
2136
2218
 
2137
2219
  x402 PAYMENTS:
2138
2220
  x402 <url> [--method GET|POST] [--body <json>] Make a paid API call