@agether/sdk 1.10.2 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -103,6 +103,7 @@ interface ContractAddresses {
103
103
  accountFactory: string;
104
104
  validationRegistry: string;
105
105
  agentReputation: string;
106
+ kyaHook: string;
106
107
  usdc: string;
107
108
  identityRegistry: string;
108
109
  morphoBlue: string;
@@ -176,10 +177,14 @@ declare class AgetherClient {
176
177
  }
177
178
 
178
179
  /**
179
- * MorphoClient — Direct Morpho Blue lending via AgentAccount.executeBatch
180
+ * MorphoClient — Direct Morpho Blue lending via AgentAccount (ERC-7579)
180
181
  *
181
182
  * Architecture (no intermediary contract):
182
- * EOA → AgentAccount.executeBatch → Morpho Blue (direct)
183
+ * EOA → AgentAccount.execute(MODE_BATCH, ...) → Morpho Blue (direct)
184
+ *
185
+ * ERC-7579 execution modes:
186
+ * - Single: execute(MODE_SINGLE, abi.encode(target, value, callData))
187
+ * - Batch: execute(MODE_BATCH, abi.encode(Execution[]))
183
188
  *
184
189
  * Batched operations:
185
190
  * - depositAndBorrow: [ERC20.approve, Morpho.supplyCollateral, Morpho.borrow]
@@ -342,8 +347,8 @@ declare class MorphoClient {
342
347
  constructor(config: MorphoClientConfig);
343
348
  /**
344
349
  * Check whether the KYA (Know Your Agent) code verification gate is active.
345
- * When validationRegistry is address(0), KYA is disabled agents can use
346
- * execute/executeBatch without prior code approval.
350
+ * Reads the account's installed hook and checks if it has a non-zero
351
+ * validationRegistry when set, the hook enforces KYA code approval.
347
352
  */
348
353
  isKyaRequired(): Promise<boolean>;
349
354
  /** Resolve the AgentAccount address (cached, with retry for flaky RPCs). */
@@ -535,11 +540,11 @@ declare class MorphoClient {
535
540
  */
536
541
  private _refreshSigner;
537
542
  /**
538
- * Execute a single call via AgentAccount.execute.
543
+ * Execute a single call via AgentAccount.execute (ERC-7579 single mode).
539
544
  */
540
545
  private exec;
541
546
  /**
542
- * Execute multiple calls via AgentAccount.executeBatch.
547
+ * Execute multiple calls via AgentAccount.execute (ERC-7579 batch mode).
543
548
  */
544
549
  private batch;
545
550
  /** Convert MorphoMarketParams to Solidity tuple. */
@@ -1040,6 +1045,7 @@ declare const AGENT_REPUTATION_ABI: string[];
1040
1045
  declare const VALIDATION_REGISTRY_ABI: string[];
1041
1046
  declare const MORPHO_BLUE_ABI: string[];
1042
1047
  declare const ERC20_ABI: string[];
1048
+ declare const KYA_HOOK_ABI: string[];
1043
1049
 
1044
1050
  /**
1045
1051
  * Network configurations
@@ -1063,4 +1069,4 @@ declare function getDefaultConfig(chainId: ChainId): AgetherConfig;
1063
1069
  */
1064
1070
  declare function createConfig(chainId: ChainId, options?: Partial<AgetherConfig>): AgetherConfig;
1065
1071
 
1066
- export { ACCOUNT_FACTORY_ABI, AGENT_ACCOUNT_ABI, AGENT_REPUTATION_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ERC20_ABI, type FundResult, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
1072
+ export { ACCOUNT_FACTORY_ABI, AGENT_ACCOUNT_ABI, AGENT_REPUTATION_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ERC20_ABI, type FundResult, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, KYA_HOOK_ABI, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
package/dist/index.d.ts CHANGED
@@ -103,6 +103,7 @@ interface ContractAddresses {
103
103
  accountFactory: string;
104
104
  validationRegistry: string;
105
105
  agentReputation: string;
106
+ kyaHook: string;
106
107
  usdc: string;
107
108
  identityRegistry: string;
108
109
  morphoBlue: string;
@@ -176,10 +177,14 @@ declare class AgetherClient {
176
177
  }
177
178
 
178
179
  /**
179
- * MorphoClient — Direct Morpho Blue lending via AgentAccount.executeBatch
180
+ * MorphoClient — Direct Morpho Blue lending via AgentAccount (ERC-7579)
180
181
  *
181
182
  * Architecture (no intermediary contract):
182
- * EOA → AgentAccount.executeBatch → Morpho Blue (direct)
183
+ * EOA → AgentAccount.execute(MODE_BATCH, ...) → Morpho Blue (direct)
184
+ *
185
+ * ERC-7579 execution modes:
186
+ * - Single: execute(MODE_SINGLE, abi.encode(target, value, callData))
187
+ * - Batch: execute(MODE_BATCH, abi.encode(Execution[]))
183
188
  *
184
189
  * Batched operations:
185
190
  * - depositAndBorrow: [ERC20.approve, Morpho.supplyCollateral, Morpho.borrow]
@@ -342,8 +347,8 @@ declare class MorphoClient {
342
347
  constructor(config: MorphoClientConfig);
343
348
  /**
344
349
  * Check whether the KYA (Know Your Agent) code verification gate is active.
345
- * When validationRegistry is address(0), KYA is disabled agents can use
346
- * execute/executeBatch without prior code approval.
350
+ * Reads the account's installed hook and checks if it has a non-zero
351
+ * validationRegistry when set, the hook enforces KYA code approval.
347
352
  */
348
353
  isKyaRequired(): Promise<boolean>;
349
354
  /** Resolve the AgentAccount address (cached, with retry for flaky RPCs). */
@@ -535,11 +540,11 @@ declare class MorphoClient {
535
540
  */
536
541
  private _refreshSigner;
537
542
  /**
538
- * Execute a single call via AgentAccount.execute.
543
+ * Execute a single call via AgentAccount.execute (ERC-7579 single mode).
539
544
  */
540
545
  private exec;
541
546
  /**
542
- * Execute multiple calls via AgentAccount.executeBatch.
547
+ * Execute multiple calls via AgentAccount.execute (ERC-7579 batch mode).
543
548
  */
544
549
  private batch;
545
550
  /** Convert MorphoMarketParams to Solidity tuple. */
@@ -1040,6 +1045,7 @@ declare const AGENT_REPUTATION_ABI: string[];
1040
1045
  declare const VALIDATION_REGISTRY_ABI: string[];
1041
1046
  declare const MORPHO_BLUE_ABI: string[];
1042
1047
  declare const ERC20_ABI: string[];
1048
+ declare const KYA_HOOK_ABI: string[];
1043
1049
 
1044
1050
  /**
1045
1051
  * Network configurations
@@ -1063,4 +1069,4 @@ declare function getDefaultConfig(chainId: ChainId): AgetherConfig;
1063
1069
  */
1064
1070
  declare function createConfig(chainId: ChainId, options?: Partial<AgetherConfig>): AgetherConfig;
1065
1071
 
1066
- export { ACCOUNT_FACTORY_ABI, AGENT_ACCOUNT_ABI, AGENT_REPUTATION_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ERC20_ABI, type FundResult, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
1072
+ export { ACCOUNT_FACTORY_ABI, AGENT_ACCOUNT_ABI, AGENT_REPUTATION_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ERC20_ABI, type FundResult, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, KYA_HOOK_ABI, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
package/dist/index.js CHANGED
@@ -41,6 +41,7 @@ __export(index_exports, {
41
41
  ERC20_ABI: () => ERC20_ABI,
42
42
  IDENTITY_REGISTRY_ABI: () => IDENTITY_REGISTRY_ABI,
43
43
  InsufficientBalanceError: () => InsufficientBalanceError,
44
+ KYA_HOOK_ABI: () => KYA_HOOK_ABI,
44
45
  MORPHO_BLUE_ABI: () => MORPHO_BLUE_ABI,
45
46
  MorphoClient: () => MorphoClient,
46
47
  ScoringClient: () => ScoringClient,
@@ -126,24 +127,30 @@ var ACCOUNT_FACTORY_ABI = [
126
127
  "function totalAccounts() view returns (uint256)",
127
128
  "function getAgentId(address account) view returns (uint256)",
128
129
  "function createAccount(uint256 agentId) returns (address account)",
129
- "function validationRegistry() view returns (address)",
130
- "function setValidationRegistry(address newRegistry)",
131
- "event AccountCreated(uint256 indexed agentId, address indexed account, address indexed owner)",
132
- "event ValidationRegistryUpdated(address indexed oldRegistry, address indexed newRegistry)"
130
+ "function protocolHook() view returns (address)",
131
+ "function identityRegistry() view returns (address)",
132
+ "event AccountCreated(uint256 indexed agentId, address indexed account, address indexed owner)"
133
133
  ];
134
134
  var AGENT_ACCOUNT_ABI = [
135
135
  "function agentId() view returns (uint256)",
136
136
  "function owner() view returns (address)",
137
137
  "function factory() view returns (address)",
138
- "function validationRegistry() view returns (address)",
139
138
  "function identityRegistry() view returns (address)",
140
139
  "function balanceOf(address token) view returns (uint256)",
141
140
  "function ethBalance() view returns (uint256)",
142
- "function execute(address target, uint256 value, bytes data) payable returns (bytes)",
143
- "function executeBatch(address[] targets, uint256[] values, bytes[] datas) payable returns (bytes[])",
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)
144
150
  "function fund(address token, uint256 amount)",
145
151
  "function withdraw(address token, uint256 amount, address to)",
146
152
  "function withdrawETH(uint256 amount, address to)",
153
+ // EIP-1271
147
154
  "function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
148
155
  ];
149
156
  var AGENT_REPUTATION_ABI = [
@@ -190,6 +197,10 @@ var ERC20_ABI = [
190
197
  "function symbol() view returns (string)",
191
198
  "function name() view returns (string)"
192
199
  ];
200
+ var KYA_HOOK_ABI = [
201
+ "function validationRegistry() view returns (address)",
202
+ "function setValidationRegistry(address newRegistry)"
203
+ ];
193
204
 
194
205
  // src/utils/config.ts
195
206
  var CONTRACT_ADDRESSES = {
@@ -197,14 +208,16 @@ var CONTRACT_ADDRESSES = {
197
208
  accountFactory: "0x0000000000000000000000000000000000000000",
198
209
  validationRegistry: "0x0000000000000000000000000000000000000000",
199
210
  agentReputation: "0x0000000000000000000000000000000000000000",
211
+ kyaHook: "0x0000000000000000000000000000000000000000",
200
212
  usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
201
213
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
202
214
  morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
203
215
  },
204
216
  [8453 /* Base */]: {
205
- accountFactory: "0xFab8b924fb292a736BA05AF7b4AEC2c8d05cdcbF",
206
- validationRegistry: "0x493f1551cbbC75afb2127CDBD5375ad8e8959f42",
207
- agentReputation: "0x1fcb28eE3E8F3234E653b0A7a6fb56dE11E3c203",
217
+ accountFactory: "0x89a8758E60A56EcB47247D92E05447eFd450d6Bf",
218
+ validationRegistry: "0x6f76cF69B71Dc5F9A414BCEe4583b12738E47985",
219
+ agentReputation: "0xe88f3419a2dbac70e3aF6E487b0C63e8301C6A87",
220
+ kyaHook: "0x28e50Aa9eD517E369b2806928709B44062aD9821",
208
221
  usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
209
222
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
210
223
  morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
@@ -213,6 +226,7 @@ var CONTRACT_ADDRESSES = {
213
226
  accountFactory: "0x0000000000000000000000000000000000000000",
214
227
  validationRegistry: "0x0000000000000000000000000000000000000000",
215
228
  agentReputation: "0x0000000000000000000000000000000000000000",
229
+ kyaHook: "0x0000000000000000000000000000000000000000",
216
230
  usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
217
231
  identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
218
232
  morphoBlue: "0x0000000000000000000000000000000000000000"
@@ -221,6 +235,7 @@ var CONTRACT_ADDRESSES = {
221
235
  accountFactory: "0x0000000000000000000000000000000000000000",
222
236
  validationRegistry: "0x0000000000000000000000000000000000000000",
223
237
  agentReputation: "0x0000000000000000000000000000000000000000",
238
+ kyaHook: "0x0000000000000000000000000000000000000000",
224
239
  usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
225
240
  identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
226
241
  morphoBlue: "0x0000000000000000000000000000000000000000"
@@ -229,6 +244,7 @@ var CONTRACT_ADDRESSES = {
229
244
  accountFactory: "0x0000000000000000000000000000000000000000",
230
245
  validationRegistry: "0x0000000000000000000000000000000000000000",
231
246
  agentReputation: "0x0000000000000000000000000000000000000000",
247
+ kyaHook: "0x0000000000000000000000000000000000000000",
232
248
  usdc: "0x56d4d6aEe0278c5Df2FA23Ecb32eC146C9446FDf",
233
249
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
234
250
  morphoBlue: "0x0000000000000000000000000000000000000000"
@@ -458,6 +474,8 @@ var BASE_COLLATERALS = {
458
474
  cbETH: { address: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22", symbol: "cbETH", decimals: 18 }
459
475
  };
460
476
  var MORPHO_API_URL = "https://api.morpho.org/graphql";
477
+ var MODE_SINGLE = "0x0000000000000000000000000000000000000000000000000000000000000000";
478
+ var MODE_BATCH = "0x0100000000000000000000000000000000000000000000000000000000000000";
461
479
  var morphoIface = new import_ethers2.ethers.Interface(MORPHO_BLUE_ABI);
462
480
  var erc20Iface = new import_ethers2.ethers.Interface(ERC20_ABI);
463
481
  var MorphoClient = class {
@@ -501,12 +519,21 @@ var MorphoClient = class {
501
519
  // ════════════════════════════════════════════════════════
502
520
  /**
503
521
  * Check whether the KYA (Know Your Agent) code verification gate is active.
504
- * When validationRegistry is address(0), KYA is disabled agents can use
505
- * execute/executeBatch without prior code approval.
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.
506
524
  */
507
525
  async isKyaRequired() {
508
- const registryAddr = await this.accountFactory.validationRegistry();
509
- return registryAddr !== import_ethers2.ethers.ZeroAddress;
526
+ 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();
533
+ return registryAddr !== import_ethers2.ethers.ZeroAddress;
534
+ } catch {
535
+ return false;
536
+ }
510
537
  }
511
538
  // ════════════════════════════════════════════════════════
512
539
  // Account Management
@@ -1201,26 +1228,21 @@ var MorphoClient = class {
1201
1228
  repayAssets = import_ethers2.ethers.parseUnits(usdcAmount, 6);
1202
1229
  repayShares = 0n;
1203
1230
  approveAmount = repayAssets;
1204
- try {
1205
- const markets = await this.getMarkets();
1206
- const mkt = markets.find(
1207
- (m) => m.collateralAsset?.address.toLowerCase() === params.collateralToken.toLowerCase()
1231
+ }
1232
+ const usdcContract = new import_ethers2.Contract(usdcAddr, ERC20_ABI, this._signer);
1233
+ const acctBalance = await usdcContract.balanceOf(acctAddr);
1234
+ if (acctBalance < approveAmount) {
1235
+ const shortfall = approveAmount - acctBalance;
1236
+ const eoaBalance = await usdcContract.balanceOf(await this.getSignerAddress());
1237
+ if (eoaBalance < shortfall) {
1238
+ throw new AgetherError(
1239
+ `Insufficient USDC for repay. Need ${import_ethers2.ethers.formatUnits(approveAmount, 6)} USDC, AgentAccount has ${import_ethers2.ethers.formatUnits(acctBalance, 6)}, EOA has ${import_ethers2.ethers.formatUnits(eoaBalance, 6)}.`,
1240
+ "INSUFFICIENT_BALANCE"
1208
1241
  );
1209
- if (mkt) {
1210
- const pos = await this.morphoBlue.position(mkt.uniqueKey, acctAddr);
1211
- const onChainMkt = await this.morphoBlue.market(mkt.uniqueKey);
1212
- const totalBorrowAssets = BigInt(onChainMkt.totalBorrowAssets);
1213
- const totalBorrowShares = BigInt(onChainMkt.totalBorrowShares);
1214
- const currentDebt = totalBorrowShares > 0n ? BigInt(pos.borrowShares) * totalBorrowAssets / totalBorrowShares : 0n;
1215
- if (repayAssets >= currentDebt && BigInt(pos.borrowShares) > 0n) {
1216
- repayShares = BigInt(pos.borrowShares);
1217
- repayAssets = 0n;
1218
- approveAmount = currentDebt + 10n;
1219
- }
1220
- }
1221
- } catch (e) {
1222
- console.warn("[agether] share-based repay detection failed, falling through to asset-based:", e instanceof Error ? e.message : e);
1223
1242
  }
1243
+ const transferTx = await usdcContract.transfer(acctAddr, shortfall);
1244
+ await transferTx.wait();
1245
+ this._refreshSigner();
1224
1246
  }
1225
1247
  const targets = [usdcAddr, morphoAddr];
1226
1248
  const values = [0n, 0n];
@@ -1378,39 +1400,48 @@ var MorphoClient = class {
1378
1400
  }
1379
1401
  }
1380
1402
  /**
1381
- * Execute a single call via AgentAccount.execute.
1403
+ * Execute a single call via AgentAccount.execute (ERC-7579 single mode).
1382
1404
  */
1383
1405
  async exec(target, data, value = 0n) {
1384
1406
  const acctAddr = await this.getAccountAddress();
1385
1407
  const account = new import_ethers2.Contract(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1408
+ const executionCalldata = import_ethers2.ethers.AbiCoder.defaultAbiCoder().encode(
1409
+ ["address", "uint256", "bytes"],
1410
+ [target, value, data]
1411
+ );
1386
1412
  let gasLimit;
1387
1413
  try {
1388
- const estimate = await account.execute.estimateGas(target, value, data);
1414
+ const estimate = await account.execute.estimateGas(MODE_SINGLE, executionCalldata);
1389
1415
  gasLimit = estimate * 130n / 100n;
1390
1416
  } catch (e) {
1391
1417
  console.warn("[agether] exec gas estimation failed, using default 500k:", e instanceof Error ? e.message : e);
1392
1418
  gasLimit = 500000n;
1393
1419
  }
1394
- const tx = await account.execute(target, value, data, { gasLimit });
1420
+ const tx = await account.execute(MODE_SINGLE, executionCalldata, { gasLimit });
1395
1421
  const receipt = await tx.wait();
1396
1422
  this._refreshSigner();
1397
1423
  return receipt;
1398
1424
  }
1399
1425
  /**
1400
- * Execute multiple calls via AgentAccount.executeBatch.
1426
+ * Execute multiple calls via AgentAccount.execute (ERC-7579 batch mode).
1401
1427
  */
1402
1428
  async batch(targets, values, datas) {
1403
1429
  const acctAddr = await this.getAccountAddress();
1404
1430
  const account = new import_ethers2.Contract(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1431
+ const executions = targets.map((t, i) => [t, values[i], datas[i]]);
1432
+ const executionCalldata = import_ethers2.ethers.AbiCoder.defaultAbiCoder().encode(
1433
+ ["(address,uint256,bytes)[]"],
1434
+ [executions]
1435
+ );
1405
1436
  let gasLimit;
1406
1437
  try {
1407
- const estimate = await account.executeBatch.estimateGas(targets, values, datas);
1438
+ const estimate = await account.execute.estimateGas(MODE_BATCH, executionCalldata);
1408
1439
  gasLimit = estimate * 130n / 100n;
1409
1440
  } catch (e) {
1410
1441
  console.warn("[agether] batch gas estimation failed, using default 800k:", e instanceof Error ? e.message : e);
1411
1442
  gasLimit = 800000n;
1412
1443
  }
1413
- const tx = await account.executeBatch(targets, values, datas, { gasLimit });
1444
+ const tx = await account.execute(MODE_BATCH, executionCalldata, { gasLimit });
1414
1445
  const receipt = await tx.wait();
1415
1446
  this._refreshSigner();
1416
1447
  return receipt;
@@ -2250,6 +2281,7 @@ function rateToBps(rate) {
2250
2281
  ERC20_ABI,
2251
2282
  IDENTITY_REGISTRY_ABI,
2252
2283
  InsufficientBalanceError,
2284
+ KYA_HOOK_ABI,
2253
2285
  MORPHO_BLUE_ABI,
2254
2286
  MorphoClient,
2255
2287
  ScoringClient,
package/dist/index.mjs CHANGED
@@ -62,24 +62,30 @@ var ACCOUNT_FACTORY_ABI = [
62
62
  "function totalAccounts() view returns (uint256)",
63
63
  "function getAgentId(address account) view returns (uint256)",
64
64
  "function createAccount(uint256 agentId) returns (address account)",
65
- "function validationRegistry() view returns (address)",
66
- "function setValidationRegistry(address newRegistry)",
67
- "event AccountCreated(uint256 indexed agentId, address indexed account, address indexed owner)",
68
- "event ValidationRegistryUpdated(address indexed oldRegistry, address indexed newRegistry)"
65
+ "function protocolHook() view returns (address)",
66
+ "function identityRegistry() view returns (address)",
67
+ "event AccountCreated(uint256 indexed agentId, address indexed account, address indexed owner)"
69
68
  ];
70
69
  var AGENT_ACCOUNT_ABI = [
71
70
  "function agentId() view returns (uint256)",
72
71
  "function owner() view returns (address)",
73
72
  "function factory() view returns (address)",
74
- "function validationRegistry() view returns (address)",
75
73
  "function identityRegistry() view returns (address)",
76
74
  "function balanceOf(address token) view returns (uint256)",
77
75
  "function ethBalance() view returns (uint256)",
78
- "function execute(address target, uint256 value, bytes data) payable returns (bytes)",
79
- "function executeBatch(address[] targets, uint256[] values, bytes[] datas) payable returns (bytes[])",
76
+ // ERC-7579 execution
77
+ "function execute(bytes32 mode, bytes executionCalldata) payable",
78
+ "function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
79
+ // ERC-7579 module management
80
+ "function installModule(uint256 moduleTypeId, address module, bytes initData) payable",
81
+ "function uninstallModule(uint256 moduleTypeId, address module, bytes deInitData) payable",
82
+ "function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
83
+ "function hook() view returns (address)",
84
+ // Funding (direct, no execution needed)
80
85
  "function fund(address token, uint256 amount)",
81
86
  "function withdraw(address token, uint256 amount, address to)",
82
87
  "function withdrawETH(uint256 amount, address to)",
88
+ // EIP-1271
83
89
  "function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
84
90
  ];
85
91
  var AGENT_REPUTATION_ABI = [
@@ -126,6 +132,10 @@ var ERC20_ABI = [
126
132
  "function symbol() view returns (string)",
127
133
  "function name() view returns (string)"
128
134
  ];
135
+ var KYA_HOOK_ABI = [
136
+ "function validationRegistry() view returns (address)",
137
+ "function setValidationRegistry(address newRegistry)"
138
+ ];
129
139
 
130
140
  // src/utils/config.ts
131
141
  var CONTRACT_ADDRESSES = {
@@ -133,14 +143,16 @@ var CONTRACT_ADDRESSES = {
133
143
  accountFactory: "0x0000000000000000000000000000000000000000",
134
144
  validationRegistry: "0x0000000000000000000000000000000000000000",
135
145
  agentReputation: "0x0000000000000000000000000000000000000000",
146
+ kyaHook: "0x0000000000000000000000000000000000000000",
136
147
  usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
137
148
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
138
149
  morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
139
150
  },
140
151
  [8453 /* Base */]: {
141
- accountFactory: "0xFab8b924fb292a736BA05AF7b4AEC2c8d05cdcbF",
142
- validationRegistry: "0x493f1551cbbC75afb2127CDBD5375ad8e8959f42",
143
- agentReputation: "0x1fcb28eE3E8F3234E653b0A7a6fb56dE11E3c203",
152
+ accountFactory: "0x89a8758E60A56EcB47247D92E05447eFd450d6Bf",
153
+ validationRegistry: "0x6f76cF69B71Dc5F9A414BCEe4583b12738E47985",
154
+ agentReputation: "0xe88f3419a2dbac70e3aF6E487b0C63e8301C6A87",
155
+ kyaHook: "0x28e50Aa9eD517E369b2806928709B44062aD9821",
144
156
  usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
145
157
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
146
158
  morphoBlue: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
@@ -149,6 +161,7 @@ var CONTRACT_ADDRESSES = {
149
161
  accountFactory: "0x0000000000000000000000000000000000000000",
150
162
  validationRegistry: "0x0000000000000000000000000000000000000000",
151
163
  agentReputation: "0x0000000000000000000000000000000000000000",
164
+ kyaHook: "0x0000000000000000000000000000000000000000",
152
165
  usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
153
166
  identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
154
167
  morphoBlue: "0x0000000000000000000000000000000000000000"
@@ -157,6 +170,7 @@ var CONTRACT_ADDRESSES = {
157
170
  accountFactory: "0x0000000000000000000000000000000000000000",
158
171
  validationRegistry: "0x0000000000000000000000000000000000000000",
159
172
  agentReputation: "0x0000000000000000000000000000000000000000",
173
+ kyaHook: "0x0000000000000000000000000000000000000000",
160
174
  usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
161
175
  identityRegistry: "0x8004A818BFB912233c491871b3d84c89A494BD9e",
162
176
  morphoBlue: "0x0000000000000000000000000000000000000000"
@@ -165,6 +179,7 @@ var CONTRACT_ADDRESSES = {
165
179
  accountFactory: "0x0000000000000000000000000000000000000000",
166
180
  validationRegistry: "0x0000000000000000000000000000000000000000",
167
181
  agentReputation: "0x0000000000000000000000000000000000000000",
182
+ kyaHook: "0x0000000000000000000000000000000000000000",
168
183
  usdc: "0x56d4d6aEe0278c5Df2FA23Ecb32eC146C9446FDf",
169
184
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
170
185
  morphoBlue: "0x0000000000000000000000000000000000000000"
@@ -394,6 +409,8 @@ var BASE_COLLATERALS = {
394
409
  cbETH: { address: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22", symbol: "cbETH", decimals: 18 }
395
410
  };
396
411
  var MORPHO_API_URL = "https://api.morpho.org/graphql";
412
+ var MODE_SINGLE = "0x0000000000000000000000000000000000000000000000000000000000000000";
413
+ var MODE_BATCH = "0x0100000000000000000000000000000000000000000000000000000000000000";
397
414
  var morphoIface = new ethers2.Interface(MORPHO_BLUE_ABI);
398
415
  var erc20Iface = new ethers2.Interface(ERC20_ABI);
399
416
  var MorphoClient = class {
@@ -437,12 +454,21 @@ var MorphoClient = class {
437
454
  // ════════════════════════════════════════════════════════
438
455
  /**
439
456
  * Check whether the KYA (Know Your Agent) code verification gate is active.
440
- * When validationRegistry is address(0), KYA is disabled agents can use
441
- * execute/executeBatch without prior code approval.
457
+ * Reads the account's installed hook and checks if it has a non-zero
458
+ * validationRegistry when set, the hook enforces KYA code approval.
442
459
  */
443
460
  async isKyaRequired() {
444
- const registryAddr = await this.accountFactory.validationRegistry();
445
- return registryAddr !== ethers2.ZeroAddress;
461
+ try {
462
+ const acctAddr = await this.getAccountAddress();
463
+ const account = new Contract2(acctAddr, AGENT_ACCOUNT_ABI, this.provider);
464
+ const hookAddr = await account.hook();
465
+ if (hookAddr === ethers2.ZeroAddress) return false;
466
+ const hook = new Contract2(hookAddr, KYA_HOOK_ABI, this.provider);
467
+ const registryAddr = await hook.validationRegistry();
468
+ return registryAddr !== ethers2.ZeroAddress;
469
+ } catch {
470
+ return false;
471
+ }
446
472
  }
447
473
  // ════════════════════════════════════════════════════════
448
474
  // Account Management
@@ -1137,26 +1163,21 @@ var MorphoClient = class {
1137
1163
  repayAssets = ethers2.parseUnits(usdcAmount, 6);
1138
1164
  repayShares = 0n;
1139
1165
  approveAmount = repayAssets;
1140
- try {
1141
- const markets = await this.getMarkets();
1142
- const mkt = markets.find(
1143
- (m) => m.collateralAsset?.address.toLowerCase() === params.collateralToken.toLowerCase()
1166
+ }
1167
+ const usdcContract = new Contract2(usdcAddr, ERC20_ABI, this._signer);
1168
+ const acctBalance = await usdcContract.balanceOf(acctAddr);
1169
+ if (acctBalance < approveAmount) {
1170
+ const shortfall = approveAmount - acctBalance;
1171
+ const eoaBalance = await usdcContract.balanceOf(await this.getSignerAddress());
1172
+ if (eoaBalance < shortfall) {
1173
+ throw new AgetherError(
1174
+ `Insufficient USDC for repay. Need ${ethers2.formatUnits(approveAmount, 6)} USDC, AgentAccount has ${ethers2.formatUnits(acctBalance, 6)}, EOA has ${ethers2.formatUnits(eoaBalance, 6)}.`,
1175
+ "INSUFFICIENT_BALANCE"
1144
1176
  );
1145
- if (mkt) {
1146
- const pos = await this.morphoBlue.position(mkt.uniqueKey, acctAddr);
1147
- const onChainMkt = await this.morphoBlue.market(mkt.uniqueKey);
1148
- const totalBorrowAssets = BigInt(onChainMkt.totalBorrowAssets);
1149
- const totalBorrowShares = BigInt(onChainMkt.totalBorrowShares);
1150
- const currentDebt = totalBorrowShares > 0n ? BigInt(pos.borrowShares) * totalBorrowAssets / totalBorrowShares : 0n;
1151
- if (repayAssets >= currentDebt && BigInt(pos.borrowShares) > 0n) {
1152
- repayShares = BigInt(pos.borrowShares);
1153
- repayAssets = 0n;
1154
- approveAmount = currentDebt + 10n;
1155
- }
1156
- }
1157
- } catch (e) {
1158
- console.warn("[agether] share-based repay detection failed, falling through to asset-based:", e instanceof Error ? e.message : e);
1159
1177
  }
1178
+ const transferTx = await usdcContract.transfer(acctAddr, shortfall);
1179
+ await transferTx.wait();
1180
+ this._refreshSigner();
1160
1181
  }
1161
1182
  const targets = [usdcAddr, morphoAddr];
1162
1183
  const values = [0n, 0n];
@@ -1314,39 +1335,48 @@ var MorphoClient = class {
1314
1335
  }
1315
1336
  }
1316
1337
  /**
1317
- * Execute a single call via AgentAccount.execute.
1338
+ * Execute a single call via AgentAccount.execute (ERC-7579 single mode).
1318
1339
  */
1319
1340
  async exec(target, data, value = 0n) {
1320
1341
  const acctAddr = await this.getAccountAddress();
1321
1342
  const account = new Contract2(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1343
+ const executionCalldata = ethers2.AbiCoder.defaultAbiCoder().encode(
1344
+ ["address", "uint256", "bytes"],
1345
+ [target, value, data]
1346
+ );
1322
1347
  let gasLimit;
1323
1348
  try {
1324
- const estimate = await account.execute.estimateGas(target, value, data);
1349
+ const estimate = await account.execute.estimateGas(MODE_SINGLE, executionCalldata);
1325
1350
  gasLimit = estimate * 130n / 100n;
1326
1351
  } catch (e) {
1327
1352
  console.warn("[agether] exec gas estimation failed, using default 500k:", e instanceof Error ? e.message : e);
1328
1353
  gasLimit = 500000n;
1329
1354
  }
1330
- const tx = await account.execute(target, value, data, { gasLimit });
1355
+ const tx = await account.execute(MODE_SINGLE, executionCalldata, { gasLimit });
1331
1356
  const receipt = await tx.wait();
1332
1357
  this._refreshSigner();
1333
1358
  return receipt;
1334
1359
  }
1335
1360
  /**
1336
- * Execute multiple calls via AgentAccount.executeBatch.
1361
+ * Execute multiple calls via AgentAccount.execute (ERC-7579 batch mode).
1337
1362
  */
1338
1363
  async batch(targets, values, datas) {
1339
1364
  const acctAddr = await this.getAccountAddress();
1340
1365
  const account = new Contract2(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
1366
+ const executions = targets.map((t, i) => [t, values[i], datas[i]]);
1367
+ const executionCalldata = ethers2.AbiCoder.defaultAbiCoder().encode(
1368
+ ["(address,uint256,bytes)[]"],
1369
+ [executions]
1370
+ );
1341
1371
  let gasLimit;
1342
1372
  try {
1343
- const estimate = await account.executeBatch.estimateGas(targets, values, datas);
1373
+ const estimate = await account.execute.estimateGas(MODE_BATCH, executionCalldata);
1344
1374
  gasLimit = estimate * 130n / 100n;
1345
1375
  } catch (e) {
1346
1376
  console.warn("[agether] batch gas estimation failed, using default 800k:", e instanceof Error ? e.message : e);
1347
1377
  gasLimit = 800000n;
1348
1378
  }
1349
- const tx = await account.executeBatch(targets, values, datas, { gasLimit });
1379
+ const tx = await account.execute(MODE_BATCH, executionCalldata, { gasLimit });
1350
1380
  const receipt = await tx.wait();
1351
1381
  this._refreshSigner();
1352
1382
  return receipt;
@@ -2185,6 +2215,7 @@ export {
2185
2215
  ERC20_ABI,
2186
2216
  IDENTITY_REGISTRY_ABI,
2187
2217
  InsufficientBalanceError,
2218
+ KYA_HOOK_ABI,
2188
2219
  MORPHO_BLUE_ABI,
2189
2220
  MorphoClient,
2190
2221
  ScoringClient,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agether/sdk",
3
- "version": "1.10.2",
3
+ "version": "1.11.1",
4
4
  "description": "TypeScript SDK for Agether - autonomous credit for AI agents on Base",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",