@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 +1 -1
- package/dist/cli.js +211 -129
- package/dist/index.d.mts +101 -52
- package/dist/index.d.ts +101 -52
- package/dist/index.js +279 -180
- package/dist/index.mjs +270 -178
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -55,40 +55,45 @@ var IDENTITY_REGISTRY_ABI = [
|
|
|
55
55
|
"function register() returns (uint256 agentId)",
|
|
56
56
|
"event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)"
|
|
57
57
|
];
|
|
58
|
-
var
|
|
58
|
+
var AGETHER_4337_FACTORY_ABI = [
|
|
59
59
|
"function getAccount(uint256 agentId) view returns (address)",
|
|
60
60
|
"function accountExists(uint256 agentId) view returns (bool)",
|
|
61
|
-
"function predictAddress(uint256 agentId) view returns (address)",
|
|
62
61
|
"function totalAccounts() view returns (uint256)",
|
|
63
62
|
"function getAgentId(address account) view returns (uint256)",
|
|
64
|
-
"function
|
|
65
|
-
"function
|
|
63
|
+
"function getAgentIdByIndex(uint256 index) view returns (uint256)",
|
|
64
|
+
"function getAllAgentIds() view returns (uint256[])",
|
|
65
|
+
"function createAccount(uint256 agentId) returns (address safeAccount)",
|
|
66
66
|
"function identityRegistry() view returns (address)",
|
|
67
|
-
"
|
|
67
|
+
"function validationModule() view returns (address)",
|
|
68
|
+
"function hookMultiplexer() view returns (address)",
|
|
69
|
+
"function safeSingleton() view returns (address)",
|
|
70
|
+
"function safe7579() view returns (address)",
|
|
71
|
+
"function bootstrap() view returns (address)",
|
|
72
|
+
"event AccountCreated(uint256 indexed agentId, address indexed safeAccount, address indexed owner)"
|
|
68
73
|
];
|
|
69
|
-
var
|
|
70
|
-
|
|
74
|
+
var SAFE_AGENT_FACTORY_ABI = AGETHER_4337_FACTORY_ABI;
|
|
75
|
+
var ACCOUNT_FACTORY_ABI = AGETHER_4337_FACTORY_ABI;
|
|
76
|
+
var AGETHER_8004_VALIDATION_MODULE_ABI = [
|
|
77
|
+
// View
|
|
78
|
+
"function getConfig(address account) view returns (address registry, uint256 agentId)",
|
|
79
|
+
"function getOwner(address account) view returns (address)",
|
|
80
|
+
"function isInstalled(address account) view returns (bool)",
|
|
81
|
+
"function isKYAApproved(address account) view returns (bool)",
|
|
82
|
+
"function validationRegistry() view returns (address)",
|
|
71
83
|
"function owner() view returns (address)",
|
|
72
|
-
|
|
73
|
-
"function
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"function
|
|
78
|
-
"function
|
|
79
|
-
|
|
80
|
-
"function
|
|
81
|
-
"function
|
|
82
|
-
"function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
|
|
83
|
-
"function hook() view returns (address)",
|
|
84
|
-
// Funding (direct, no execution needed)
|
|
85
|
-
"function fund(address token, uint256 amount)",
|
|
86
|
-
"function withdraw(address token, uint256 amount, address to)",
|
|
87
|
-
"function withdrawETH(uint256 amount, address to)",
|
|
88
|
-
// EIP-1271
|
|
89
|
-
"function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
|
|
84
|
+
// Admin (via TimelockController)
|
|
85
|
+
"function setValidationRegistry(address registry_)"
|
|
86
|
+
];
|
|
87
|
+
var ERC8004_VALIDATION_MODULE_ABI = AGETHER_8004_VALIDATION_MODULE_ABI;
|
|
88
|
+
var AGETHER_HOOK_MULTIPLEXER_ABI = [
|
|
89
|
+
"function getHooks() view returns (address[])",
|
|
90
|
+
"function hookCount() view returns (uint256)",
|
|
91
|
+
"function owner() view returns (address)",
|
|
92
|
+
"function addHook(address hook)",
|
|
93
|
+
"function removeHook(address hook)"
|
|
90
94
|
];
|
|
91
|
-
var
|
|
95
|
+
var HOOK_MULTIPLEXER_ABI = AGETHER_HOOK_MULTIPLEXER_ABI;
|
|
96
|
+
var AGETHER_8004_SCORER_ABI = [
|
|
92
97
|
"function getCreditScore(uint256 agentId) view returns (uint256)",
|
|
93
98
|
"function getAttestation(uint256 agentId) view returns (tuple(uint256 score, uint256 timestamp, address signer))",
|
|
94
99
|
"function isScoreFresh(uint256 agentId) view returns (bool fresh, uint256 age)",
|
|
@@ -98,6 +103,7 @@ var AGENT_REPUTATION_ABI = [
|
|
|
98
103
|
"function setOracleSigner(address signer_)",
|
|
99
104
|
"event ScoreUpdated(uint256 indexed agentId, uint256 score, uint256 timestamp, address signer)"
|
|
100
105
|
];
|
|
106
|
+
var AGENT_REPUTATION_ABI = AGETHER_8004_SCORER_ABI;
|
|
101
107
|
var VALIDATION_REGISTRY_ABI = [
|
|
102
108
|
"function isAgentCodeApproved(uint256 agentId) view returns (bool)",
|
|
103
109
|
"function isAgentCodeApprovedForTag(uint256 agentId, string tag) view returns (bool)",
|
|
@@ -132,57 +138,113 @@ var ERC20_ABI = [
|
|
|
132
138
|
"function symbol() view returns (string)",
|
|
133
139
|
"function name() view returns (string)"
|
|
134
140
|
];
|
|
135
|
-
var
|
|
136
|
-
"function
|
|
137
|
-
"function
|
|
141
|
+
var ENTRYPOINT_V07_ABI = [
|
|
142
|
+
"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)",
|
|
143
|
+
"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)",
|
|
144
|
+
"function getNonce(address sender, uint192 key) view returns (uint256 nonce)",
|
|
145
|
+
"function balanceOf(address account) view returns (uint256)",
|
|
146
|
+
"function depositTo(address account) payable",
|
|
147
|
+
"event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed)"
|
|
148
|
+
];
|
|
149
|
+
var SAFE7579_ACCOUNT_ABI = [
|
|
150
|
+
// ERC-7579 execution (called via UserOp through Safe7579 fallback)
|
|
151
|
+
"function execute(bytes32 mode, bytes executionCalldata) payable",
|
|
152
|
+
"function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
|
|
153
|
+
// ERC-7579 module queries
|
|
154
|
+
"function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
|
|
155
|
+
// EIP-1271
|
|
156
|
+
"function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
|
|
138
157
|
];
|
|
139
158
|
|
|
140
159
|
// src/utils/config.ts
|
|
160
|
+
var ZERO = "0x0000000000000000000000000000000000000000";
|
|
161
|
+
var ENTRYPOINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
|
|
162
|
+
var ERC8004_IDENTITY_REGISTRY = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
|
|
163
|
+
var ERC8004_IDENTITY_REGISTRY_TESTNET = "0x8004A818BFB912233c491871b3d84c89A494BD9e";
|
|
164
|
+
var MORPHO_BLUE = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
|
|
165
|
+
var SAFE_SINGLETON = "0x41675C099F32341bf84BFc5382aF534df5C7461a";
|
|
166
|
+
var SAFE_PROXY_FACTORY = "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67";
|
|
167
|
+
var SAFE7579 = "0x7579EE8307284F293B1927136486880611F20002";
|
|
141
168
|
var CONTRACT_ADDRESSES = {
|
|
142
169
|
[1 /* Ethereum */]: {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
170
|
+
safeSingleton: SAFE_SINGLETON,
|
|
171
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
172
|
+
safe7579: SAFE7579,
|
|
173
|
+
entryPoint: ENTRYPOINT_V07,
|
|
174
|
+
agether4337Factory: ZERO,
|
|
175
|
+
agether7579Bootstrap: ZERO,
|
|
176
|
+
erc8004ValidationModule: ZERO,
|
|
177
|
+
agetherHookMultiplexer: ZERO,
|
|
178
|
+
validationRegistry: ZERO,
|
|
179
|
+
agether8004Scorer: ZERO,
|
|
180
|
+
timelockController: ZERO,
|
|
147
181
|
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
148
|
-
identityRegistry:
|
|
149
|
-
morphoBlue:
|
|
182
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY,
|
|
183
|
+
morphoBlue: MORPHO_BLUE
|
|
150
184
|
},
|
|
151
185
|
[8453 /* Base */]: {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
186
|
+
safeSingleton: SAFE_SINGLETON,
|
|
187
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
188
|
+
safe7579: SAFE7579,
|
|
189
|
+
entryPoint: ENTRYPOINT_V07,
|
|
190
|
+
agether4337Factory: "0x7B23470dCD65b8fEA3Bf49466860b3A55D56268C",
|
|
191
|
+
agether7579Bootstrap: "0x62d34D22D379367EEDcb7D1E4dE899A654E982D0",
|
|
192
|
+
erc8004ValidationModule: "0xfC6ccFd12e163460C7Ef92d38DC0be6C6cA10f6C",
|
|
193
|
+
agetherHookMultiplexer: "0x094FE93a8b733a97a6945530cA83058CaCbf5278",
|
|
194
|
+
validationRegistry: ZERO,
|
|
195
|
+
agether8004Scorer: "0x9f0084E5c941365149c8953133cF062E33a19b8d",
|
|
196
|
+
timelockController: "0x2807912DA2a7278AF883a376bE15bBBf3ab99f52",
|
|
156
197
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
157
|
-
identityRegistry:
|
|
158
|
-
morphoBlue:
|
|
198
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY,
|
|
199
|
+
morphoBlue: MORPHO_BLUE
|
|
159
200
|
},
|
|
160
201
|
[84532 /* BaseSepolia */]: {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
202
|
+
safeSingleton: SAFE_SINGLETON,
|
|
203
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
204
|
+
safe7579: SAFE7579,
|
|
205
|
+
entryPoint: ENTRYPOINT_V07,
|
|
206
|
+
agether4337Factory: ZERO,
|
|
207
|
+
agether7579Bootstrap: ZERO,
|
|
208
|
+
erc8004ValidationModule: ZERO,
|
|
209
|
+
agetherHookMultiplexer: ZERO,
|
|
210
|
+
validationRegistry: ZERO,
|
|
211
|
+
agether8004Scorer: ZERO,
|
|
212
|
+
timelockController: ZERO,
|
|
165
213
|
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
166
|
-
identityRegistry:
|
|
167
|
-
morphoBlue:
|
|
214
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
|
|
215
|
+
morphoBlue: ZERO
|
|
168
216
|
},
|
|
169
217
|
[11155111 /* Sepolia */]: {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
218
|
+
safeSingleton: SAFE_SINGLETON,
|
|
219
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
220
|
+
safe7579: SAFE7579,
|
|
221
|
+
entryPoint: ENTRYPOINT_V07,
|
|
222
|
+
agether4337Factory: ZERO,
|
|
223
|
+
agether7579Bootstrap: ZERO,
|
|
224
|
+
erc8004ValidationModule: ZERO,
|
|
225
|
+
agetherHookMultiplexer: ZERO,
|
|
226
|
+
validationRegistry: ZERO,
|
|
227
|
+
agether8004Scorer: ZERO,
|
|
228
|
+
timelockController: ZERO,
|
|
174
229
|
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
175
|
-
identityRegistry:
|
|
176
|
-
morphoBlue:
|
|
230
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
|
|
231
|
+
morphoBlue: ZERO
|
|
177
232
|
},
|
|
178
233
|
[31337 /* Hardhat */]: {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
234
|
+
safeSingleton: SAFE_SINGLETON,
|
|
235
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
236
|
+
safe7579: SAFE7579,
|
|
237
|
+
entryPoint: ENTRYPOINT_V07,
|
|
238
|
+
agether4337Factory: ZERO,
|
|
239
|
+
agether7579Bootstrap: ZERO,
|
|
240
|
+
erc8004ValidationModule: ZERO,
|
|
241
|
+
agetherHookMultiplexer: ZERO,
|
|
242
|
+
validationRegistry: ZERO,
|
|
243
|
+
agether8004Scorer: ZERO,
|
|
244
|
+
timelockController: ZERO,
|
|
183
245
|
usdc: "0x56d4d6aEe0278c5Df2FA23Ecb32eC146C9446FDf",
|
|
184
|
-
identityRegistry:
|
|
185
|
-
morphoBlue:
|
|
246
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY,
|
|
247
|
+
morphoBlue: ZERO
|
|
186
248
|
}
|
|
187
249
|
};
|
|
188
250
|
var RPC_URLS = {
|
|
@@ -227,9 +289,9 @@ var AgetherClient = class _AgetherClient {
|
|
|
227
289
|
this.agentId = options.agentId;
|
|
228
290
|
const provider = options.signer.provider;
|
|
229
291
|
if (!provider) throw new AgetherError("Signer must have a provider", "NO_PROVIDER");
|
|
230
|
-
this.
|
|
231
|
-
options.config.contracts.
|
|
232
|
-
|
|
292
|
+
this.agether4337Factory = new Contract(
|
|
293
|
+
options.config.contracts.agether4337Factory,
|
|
294
|
+
AGETHER_4337_FACTORY_ABI,
|
|
233
295
|
options.signer
|
|
234
296
|
);
|
|
235
297
|
this.identityRegistry = new Contract(
|
|
@@ -237,14 +299,14 @@ var AgetherClient = class _AgetherClient {
|
|
|
237
299
|
IDENTITY_REGISTRY_ABI,
|
|
238
300
|
provider
|
|
239
301
|
);
|
|
240
|
-
this.
|
|
241
|
-
options.config.contracts.
|
|
242
|
-
|
|
302
|
+
this.agether8004Scorer = new Contract(
|
|
303
|
+
options.config.contracts.agether8004Scorer,
|
|
304
|
+
AGETHER_8004_SCORER_ABI,
|
|
243
305
|
provider
|
|
244
306
|
);
|
|
245
|
-
this.
|
|
246
|
-
options.config.contracts.
|
|
247
|
-
|
|
307
|
+
this.validationModule = new Contract(
|
|
308
|
+
options.config.contracts.erc8004ValidationModule,
|
|
309
|
+
AGETHER_8004_VALIDATION_MODULE_ABI,
|
|
248
310
|
provider
|
|
249
311
|
);
|
|
250
312
|
}
|
|
@@ -257,26 +319,26 @@ var AgetherClient = class _AgetherClient {
|
|
|
257
319
|
}
|
|
258
320
|
// Account Management
|
|
259
321
|
async createAccount() {
|
|
260
|
-
const tx = await this.
|
|
322
|
+
const tx = await this.agether4337Factory.createAccount(this.agentId);
|
|
261
323
|
const receipt = await tx.wait();
|
|
262
324
|
const event = receipt.logs.map((log) => {
|
|
263
325
|
try {
|
|
264
|
-
return this.
|
|
326
|
+
return this.agether4337Factory.interface.parseLog(log);
|
|
265
327
|
} catch (e) {
|
|
266
328
|
console.warn("[agether] createAccount parseLog skip:", e instanceof Error ? e.message : e);
|
|
267
329
|
return null;
|
|
268
330
|
}
|
|
269
331
|
}).find((e) => e?.name === "AccountCreated");
|
|
270
332
|
if (event) {
|
|
271
|
-
this.accountAddress = event.args.
|
|
333
|
+
this.accountAddress = event.args.safeAccount;
|
|
272
334
|
} else {
|
|
273
|
-
this.accountAddress = await this.
|
|
335
|
+
this.accountAddress = await this.agether4337Factory.getAccount(this.agentId);
|
|
274
336
|
}
|
|
275
337
|
return this.accountAddress;
|
|
276
338
|
}
|
|
277
339
|
async getAccountAddress() {
|
|
278
340
|
if (this.accountAddress) return this.accountAddress;
|
|
279
|
-
const addr = await this.
|
|
341
|
+
const addr = await this.agether4337Factory.getAccount(this.agentId);
|
|
280
342
|
if (addr === ethers.ZeroAddress) {
|
|
281
343
|
throw new AgetherError("No account found. Create one with createAccount().", "NO_ACCOUNT");
|
|
282
344
|
}
|
|
@@ -284,10 +346,7 @@ var AgetherClient = class _AgetherClient {
|
|
|
284
346
|
return addr;
|
|
285
347
|
}
|
|
286
348
|
async accountExists() {
|
|
287
|
-
return this.
|
|
288
|
-
}
|
|
289
|
-
async predictAddress() {
|
|
290
|
-
return this.accountFactory.predictAddress(this.agentId);
|
|
349
|
+
return this.agether4337Factory.accountExists(this.agentId);
|
|
291
350
|
}
|
|
292
351
|
// Balances
|
|
293
352
|
async getBalances() {
|
|
@@ -309,10 +368,14 @@ var AgetherClient = class _AgetherClient {
|
|
|
309
368
|
usdc: ethers.formatUnits(acctUsdc, 6)
|
|
310
369
|
};
|
|
311
370
|
} catch (e) {
|
|
312
|
-
console.warn("[agether] getBalances: no
|
|
371
|
+
console.warn("[agether] getBalances: no Safe account or fetch failed:", e instanceof Error ? e.message : e);
|
|
313
372
|
}
|
|
314
373
|
return result;
|
|
315
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Fund the Safe account with USDC from EOA.
|
|
377
|
+
* This is a simple ERC-20 transfer (does NOT require a UserOp).
|
|
378
|
+
*/
|
|
316
379
|
async fundAccount(usdcAmount) {
|
|
317
380
|
const acctAddr = await this.getAccountAddress();
|
|
318
381
|
const usdc = new Contract(this.config.contracts.usdc, ERC20_ABI, this.signer);
|
|
@@ -326,37 +389,30 @@ var AgetherClient = class _AgetherClient {
|
|
|
326
389
|
gasUsed: receipt.gasUsed
|
|
327
390
|
};
|
|
328
391
|
}
|
|
329
|
-
async withdrawUsdc(usdcAmount) {
|
|
330
|
-
const acctAddr = await this.getAccountAddress();
|
|
331
|
-
const account = new Contract(acctAddr, AGENT_ACCOUNT_ABI, this.signer);
|
|
332
|
-
const amount = ethers.parseUnits(usdcAmount, 6);
|
|
333
|
-
const eoaAddr = await this.signer.getAddress();
|
|
334
|
-
const tx = await account.withdraw(this.config.contracts.usdc, amount, eoaAddr);
|
|
335
|
-
const receipt = await tx.wait();
|
|
336
|
-
return {
|
|
337
|
-
txHash: receipt.hash,
|
|
338
|
-
blockNumber: receipt.blockNumber,
|
|
339
|
-
status: receipt.status === 1 ? "success" : "failed",
|
|
340
|
-
gasUsed: receipt.gasUsed
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
async withdrawEth(ethAmount) {
|
|
344
|
-
const acctAddr = await this.getAccountAddress();
|
|
345
|
-
const account = new Contract(acctAddr, AGENT_ACCOUNT_ABI, this.signer);
|
|
346
|
-
const amount = ethers.parseEther(ethAmount);
|
|
347
|
-
const eoaAddr = await this.signer.getAddress();
|
|
348
|
-
const tx = await account.withdrawETH(amount, eoaAddr);
|
|
349
|
-
const receipt = await tx.wait();
|
|
350
|
-
return {
|
|
351
|
-
txHash: receipt.hash,
|
|
352
|
-
blockNumber: receipt.blockNumber,
|
|
353
|
-
status: receipt.status === 1 ? "success" : "failed",
|
|
354
|
-
gasUsed: receipt.gasUsed
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
392
|
// Identity & Validation
|
|
393
|
+
/**
|
|
394
|
+
* Check if the KYA gate is active on the validation module.
|
|
395
|
+
* If validationRegistry is not set, all txs pass (KYA disabled).
|
|
396
|
+
*/
|
|
397
|
+
async isKyaRequired() {
|
|
398
|
+
try {
|
|
399
|
+
const registryAddr = await this.validationModule.validationRegistry();
|
|
400
|
+
return registryAddr !== ethers.ZeroAddress;
|
|
401
|
+
} catch {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Check if this agent's code is KYA-approved.
|
|
407
|
+
* Uses the ERC8004ValidationModule.isKYAApproved(account) view.
|
|
408
|
+
*/
|
|
358
409
|
async isKyaApproved() {
|
|
359
|
-
|
|
410
|
+
try {
|
|
411
|
+
const acctAddr = await this.getAccountAddress();
|
|
412
|
+
return this.validationModule.isKYAApproved(acctAddr);
|
|
413
|
+
} catch {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
360
416
|
}
|
|
361
417
|
async identityExists() {
|
|
362
418
|
try {
|
|
@@ -372,14 +428,14 @@ var AgetherClient = class _AgetherClient {
|
|
|
372
428
|
}
|
|
373
429
|
// Reputation
|
|
374
430
|
async getCreditScore() {
|
|
375
|
-
return this.
|
|
431
|
+
return this.agether8004Scorer.getCreditScore(this.agentId);
|
|
376
432
|
}
|
|
377
433
|
async isScoreFresh() {
|
|
378
|
-
const [fresh, age] = await this.
|
|
434
|
+
const [fresh, age] = await this.agether8004Scorer.isScoreFresh(this.agentId);
|
|
379
435
|
return { fresh, age };
|
|
380
436
|
}
|
|
381
437
|
async isEligible(minScore = 500n) {
|
|
382
|
-
const [eligible, currentScore] = await this.
|
|
438
|
+
const [eligible, currentScore] = await this.agether8004Scorer.isEligible(this.agentId, minScore);
|
|
383
439
|
return { eligible, currentScore };
|
|
384
440
|
}
|
|
385
441
|
// Getters
|
|
@@ -444,27 +500,24 @@ var MorphoClient = class {
|
|
|
444
500
|
this._eoaAddress = wallet.address;
|
|
445
501
|
}
|
|
446
502
|
const addrs = { ...defaultCfg.contracts, ...config.contracts };
|
|
447
|
-
this.
|
|
503
|
+
this.agether4337Factory = new Contract2(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
|
|
448
504
|
this.morphoBlue = new Contract2(addrs.morphoBlue, MORPHO_BLUE_ABI, this.provider);
|
|
449
|
-
this.
|
|
505
|
+
this.agether8004Scorer = new Contract2(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
|
|
450
506
|
this.identityRegistry = new Contract2(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
|
|
507
|
+
this.entryPoint = new Contract2(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
|
|
508
|
+
this.validationModule = new Contract2(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
|
|
451
509
|
}
|
|
452
510
|
// ════════════════════════════════════════════════════════
|
|
453
511
|
// KYA Gate Check
|
|
454
512
|
// ════════════════════════════════════════════════════════
|
|
455
513
|
/**
|
|
456
514
|
* Check whether the KYA (Know Your Agent) code verification gate is active.
|
|
457
|
-
* Reads the
|
|
458
|
-
*
|
|
515
|
+
* Reads the ERC8004ValidationModule's validationRegistry — when set to
|
|
516
|
+
* a non-zero address, the module enforces KYA code approval.
|
|
459
517
|
*/
|
|
460
518
|
async isKyaRequired() {
|
|
461
519
|
try {
|
|
462
|
-
const
|
|
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();
|
|
520
|
+
const registryAddr = await this.validationModule.validationRegistry();
|
|
468
521
|
return registryAddr !== ethers2.ZeroAddress;
|
|
469
522
|
} catch {
|
|
470
523
|
return false;
|
|
@@ -481,7 +534,7 @@ var MorphoClient = class {
|
|
|
481
534
|
let lastErr;
|
|
482
535
|
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
483
536
|
try {
|
|
484
|
-
const addr = await this.
|
|
537
|
+
const addr = await this.agether4337Factory.getAccount(BigInt(this.agentId));
|
|
485
538
|
if (addr === ethers2.ZeroAddress) {
|
|
486
539
|
throw new AgetherError("No AgentAccount found. Call register() first.", "NO_ACCOUNT");
|
|
487
540
|
}
|
|
@@ -559,9 +612,9 @@ var MorphoClient = class {
|
|
|
559
612
|
async register(_name) {
|
|
560
613
|
const eoaAddr = await this.getSignerAddress();
|
|
561
614
|
if (this.agentId) {
|
|
562
|
-
const exists = await this.
|
|
615
|
+
const exists = await this.agether4337Factory.accountExists(BigInt(this.agentId));
|
|
563
616
|
if (exists) {
|
|
564
|
-
const acct = await this.
|
|
617
|
+
const acct = await this.agether4337Factory.getAccount(BigInt(this.agentId));
|
|
565
618
|
this._accountAddress = acct;
|
|
566
619
|
const kyaRequired2 = await this.isKyaRequired();
|
|
567
620
|
return { agentId: this.agentId, address: eoaAddr, agentAccount: acct, alreadyRegistered: true, kyaRequired: kyaRequired2 };
|
|
@@ -579,15 +632,15 @@ var MorphoClient = class {
|
|
|
579
632
|
agentId = await this._mintNewIdentity();
|
|
580
633
|
}
|
|
581
634
|
this.agentId = agentId.toString();
|
|
582
|
-
const acctExists = await this.
|
|
635
|
+
const acctExists = await this.agether4337Factory.accountExists(agentId);
|
|
583
636
|
let txHash;
|
|
584
637
|
if (!acctExists) {
|
|
585
|
-
const tx = await this.
|
|
638
|
+
const tx = await this.agether4337Factory.createAccount(agentId);
|
|
586
639
|
const receipt = await tx.wait();
|
|
587
640
|
this._refreshSigner();
|
|
588
641
|
txHash = receipt.hash;
|
|
589
642
|
}
|
|
590
|
-
const acctAddr = await this.
|
|
643
|
+
const acctAddr = await this.agether4337Factory.getAccount(agentId);
|
|
591
644
|
this._accountAddress = acctAddr;
|
|
592
645
|
const kyaRequired = await this.isKyaRequired();
|
|
593
646
|
return {
|
|
@@ -731,7 +784,7 @@ var MorphoClient = class {
|
|
|
731
784
|
}
|
|
732
785
|
/**
|
|
733
786
|
* Get MarketParams for a collateral token.
|
|
734
|
-
* Tries cache → API →
|
|
787
|
+
* Tries cache → API → onchain idToMarketParams.
|
|
735
788
|
*/
|
|
736
789
|
async findMarketForCollateral(collateralSymbolOrAddress) {
|
|
737
790
|
const colInfo = BASE_COLLATERALS[collateralSymbolOrAddress];
|
|
@@ -746,7 +799,7 @@ var MorphoClient = class {
|
|
|
746
799
|
"MARKET_NOT_FOUND"
|
|
747
800
|
);
|
|
748
801
|
}
|
|
749
|
-
/** Read MarketParams
|
|
802
|
+
/** Read MarketParams onchain by market ID (bytes32). */
|
|
750
803
|
async getMarketParams(marketId) {
|
|
751
804
|
const result = await this.morphoBlue.idToMarketParams(marketId);
|
|
752
805
|
return {
|
|
@@ -760,7 +813,7 @@ var MorphoClient = class {
|
|
|
760
813
|
// ════════════════════════════════════════════════════════
|
|
761
814
|
// Position Reads
|
|
762
815
|
// ════════════════════════════════════════════════════════
|
|
763
|
-
/** Read
|
|
816
|
+
/** Read onchain position for a specific market. */
|
|
764
817
|
async getPosition(marketId) {
|
|
765
818
|
const acctAddr = await this.getAccountAddress();
|
|
766
819
|
const pos = await this.morphoBlue.position(marketId, acctAddr);
|
|
@@ -1314,7 +1367,7 @@ var MorphoClient = class {
|
|
|
1314
1367
|
if (target.address) {
|
|
1315
1368
|
targetAddr = target.address;
|
|
1316
1369
|
} else if (target.agentId) {
|
|
1317
|
-
targetAddr = await this.
|
|
1370
|
+
targetAddr = await this.agether4337Factory.getAccount(BigInt(target.agentId));
|
|
1318
1371
|
if (targetAddr === ethers2.ZeroAddress) throw new AgetherError("Target agent has no account", "NO_ACCOUNT");
|
|
1319
1372
|
} else {
|
|
1320
1373
|
throw new AgetherError("Provide agentId or address", "INVALID_TARGET");
|
|
@@ -1327,25 +1380,25 @@ var MorphoClient = class {
|
|
|
1327
1380
|
return { tx: receipt.hash, targetAccount: targetAddr, targetAgentId: target.agentId };
|
|
1328
1381
|
}
|
|
1329
1382
|
// ════════════════════════════════════════════════════════
|
|
1330
|
-
// Reputation (
|
|
1383
|
+
// Reputation (Agether8004Scorer contract)
|
|
1331
1384
|
// ════════════════════════════════════════════════════════
|
|
1332
1385
|
async getCreditScore() {
|
|
1333
1386
|
if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
|
|
1334
|
-
return this.
|
|
1387
|
+
return this.agether8004Scorer.getCreditScore(BigInt(this.agentId));
|
|
1335
1388
|
}
|
|
1336
1389
|
async getAttestation() {
|
|
1337
1390
|
if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
|
|
1338
|
-
const att = await this.
|
|
1391
|
+
const att = await this.agether8004Scorer.getAttestation(BigInt(this.agentId));
|
|
1339
1392
|
return { score: att.score, timestamp: att.timestamp, signer: att.signer };
|
|
1340
1393
|
}
|
|
1341
1394
|
async isEligible(minScore = 500n) {
|
|
1342
1395
|
if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
|
|
1343
|
-
const [eligible, currentScore] = await this.
|
|
1396
|
+
const [eligible, currentScore] = await this.agether8004Scorer.isEligible(BigInt(this.agentId), minScore);
|
|
1344
1397
|
return { eligible, currentScore };
|
|
1345
1398
|
}
|
|
1346
1399
|
async isScoreFresh() {
|
|
1347
1400
|
if (!this.agentId) throw new AgetherError("agentId not set", "NO_AGENT_ID");
|
|
1348
|
-
const [fresh, age] = await this.
|
|
1401
|
+
const [fresh, age] = await this.agether8004Scorer.isScoreFresh(BigInt(this.agentId));
|
|
1349
1402
|
return { fresh, age };
|
|
1350
1403
|
}
|
|
1351
1404
|
// ════════════════════════════════════════════════════════
|
|
@@ -1367,8 +1420,10 @@ var MorphoClient = class {
|
|
|
1367
1420
|
_refreshSigner() {
|
|
1368
1421
|
if (this._useExternalSigner) {
|
|
1369
1422
|
const addrs = this.config.contracts;
|
|
1370
|
-
this.
|
|
1371
|
-
this.
|
|
1423
|
+
this.agether4337Factory = new Contract2(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
|
|
1424
|
+
this.entryPoint = new Contract2(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
|
|
1425
|
+
this.validationModule = new Contract2(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
|
|
1426
|
+
this.agether8004Scorer = new Contract2(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
|
|
1372
1427
|
this.identityRegistry = new Contract2(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
|
|
1373
1428
|
} else {
|
|
1374
1429
|
this.provider = new ethers2.JsonRpcProvider(this._rpcUrl);
|
|
@@ -1376,57 +1431,87 @@ var MorphoClient = class {
|
|
|
1376
1431
|
this._signer = wallet;
|
|
1377
1432
|
this._eoaAddress = wallet.address;
|
|
1378
1433
|
const addrs = this.config.contracts;
|
|
1379
|
-
this.
|
|
1380
|
-
this.
|
|
1434
|
+
this.agether4337Factory = new Contract2(addrs.agether4337Factory, ACCOUNT_FACTORY_ABI, this._signer);
|
|
1435
|
+
this.entryPoint = new Contract2(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
|
|
1436
|
+
this.validationModule = new Contract2(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
|
|
1437
|
+
this.agether8004Scorer = new Contract2(addrs.agether8004Scorer, AGENT_REPUTATION_ABI, this._signer);
|
|
1381
1438
|
this.identityRegistry = new Contract2(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
|
|
1382
1439
|
}
|
|
1383
1440
|
}
|
|
1441
|
+
// ────────────────────────────────────────────────────────────
|
|
1442
|
+
// ERC-4337 UserOp helpers (Safe + Safe7579 + EntryPoint v0.7)
|
|
1443
|
+
// ────────────────────────────────────────────────────────────
|
|
1384
1444
|
/**
|
|
1385
|
-
*
|
|
1445
|
+
* Pack two uint128 values into a single bytes32:
|
|
1446
|
+
* bytes32 = (hi << 128) | lo
|
|
1447
|
+
*/
|
|
1448
|
+
_packUint128(hi, lo) {
|
|
1449
|
+
return ethers2.zeroPadValue(ethers2.toBeHex(hi << 128n | lo), 32);
|
|
1450
|
+
}
|
|
1451
|
+
/**
|
|
1452
|
+
* Build, sign and submit a PackedUserOperation through EntryPoint.handleOps.
|
|
1453
|
+
*
|
|
1454
|
+
* @param callData – the ABI-encoded calldata for the Safe7579 account
|
|
1455
|
+
* (e.g. `execute(mode, executionCalldata)`)
|
|
1456
|
+
* @returns the transaction receipt of the handleOps call
|
|
1457
|
+
*/
|
|
1458
|
+
async _submitUserOp(callData) {
|
|
1459
|
+
const sender = await this.getAccountAddress();
|
|
1460
|
+
const nonce = await this.entryPoint.getNonce(sender, 0);
|
|
1461
|
+
const feeData = await this.provider.getFeeData();
|
|
1462
|
+
const maxFeePerGas = feeData.maxFeePerGas ?? ethers2.parseUnits("0.5", "gwei");
|
|
1463
|
+
const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? ethers2.parseUnits("0.1", "gwei");
|
|
1464
|
+
const verificationGasLimit = 500000n;
|
|
1465
|
+
const callGasLimit = 800000n;
|
|
1466
|
+
const preVerificationGas = 100000n;
|
|
1467
|
+
const accountGasLimits = this._packUint128(verificationGasLimit, callGasLimit);
|
|
1468
|
+
const gasFees = this._packUint128(maxPriorityFeePerGas, maxFeePerGas);
|
|
1469
|
+
const userOp = {
|
|
1470
|
+
sender,
|
|
1471
|
+
nonce,
|
|
1472
|
+
initCode: "0x",
|
|
1473
|
+
callData,
|
|
1474
|
+
accountGasLimits,
|
|
1475
|
+
preVerificationGas,
|
|
1476
|
+
gasFees,
|
|
1477
|
+
paymasterAndData: "0x",
|
|
1478
|
+
signature: "0x"
|
|
1479
|
+
// placeholder — replaced after signing
|
|
1480
|
+
};
|
|
1481
|
+
const userOpHash = await this.entryPoint.getUserOpHash(userOp);
|
|
1482
|
+
const signature = await this._signer.signMessage(ethers2.getBytes(userOpHash));
|
|
1483
|
+
userOp.signature = signature;
|
|
1484
|
+
const tx = await this.entryPoint.handleOps([userOp], await this.getSignerAddress());
|
|
1485
|
+
const receipt = await tx.wait();
|
|
1486
|
+
this._refreshSigner();
|
|
1487
|
+
return receipt;
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Execute a single call via Safe7579 account (ERC-7579 single mode)
|
|
1491
|
+
* through an ERC-4337 UserOperation.
|
|
1386
1492
|
*/
|
|
1387
1493
|
async exec(target, data, value = 0n) {
|
|
1388
|
-
const acctAddr = await this.getAccountAddress();
|
|
1389
|
-
const account = new Contract2(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
|
|
1390
1494
|
const executionCalldata = ethers2.AbiCoder.defaultAbiCoder().encode(
|
|
1391
1495
|
["address", "uint256", "bytes"],
|
|
1392
1496
|
[target, value, data]
|
|
1393
1497
|
);
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
gasLimit = estimate * 130n / 100n;
|
|
1398
|
-
} catch (e) {
|
|
1399
|
-
console.warn("[agether] exec gas estimation failed, using default 500k:", e instanceof Error ? e.message : e);
|
|
1400
|
-
gasLimit = 500000n;
|
|
1401
|
-
}
|
|
1402
|
-
const tx = await account.execute(MODE_SINGLE, executionCalldata, { gasLimit });
|
|
1403
|
-
const receipt = await tx.wait();
|
|
1404
|
-
this._refreshSigner();
|
|
1405
|
-
return receipt;
|
|
1498
|
+
const safe7579Iface = new ethers2.Interface(SAFE7579_ACCOUNT_ABI);
|
|
1499
|
+
const callData = safe7579Iface.encodeFunctionData("execute", [MODE_SINGLE, executionCalldata]);
|
|
1500
|
+
return this._submitUserOp(callData);
|
|
1406
1501
|
}
|
|
1407
1502
|
/**
|
|
1408
|
-
* Execute multiple calls via
|
|
1503
|
+
* Execute multiple calls via Safe7579 account (ERC-7579 batch mode)
|
|
1504
|
+
* through an ERC-4337 UserOperation.
|
|
1409
1505
|
*/
|
|
1410
1506
|
async batch(targets, values, datas) {
|
|
1411
|
-
const acctAddr = await this.getAccountAddress();
|
|
1412
|
-
const account = new Contract2(acctAddr, AGENT_ACCOUNT_ABI, this._signer);
|
|
1413
1507
|
const executions = targets.map((t, i) => [t, values[i], datas[i]]);
|
|
1414
1508
|
const executionCalldata = ethers2.AbiCoder.defaultAbiCoder().encode(
|
|
1415
1509
|
["(address,uint256,bytes)[]"],
|
|
1416
1510
|
[executions]
|
|
1417
1511
|
);
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
gasLimit = estimate * 130n / 100n;
|
|
1422
|
-
} catch (e) {
|
|
1423
|
-
console.warn("[agether] batch gas estimation failed, using default 800k:", e instanceof Error ? e.message : e);
|
|
1424
|
-
gasLimit = 800000n;
|
|
1425
|
-
}
|
|
1426
|
-
const tx = await account.execute(MODE_BATCH, executionCalldata, { gasLimit });
|
|
1427
|
-
const receipt = await tx.wait();
|
|
1428
|
-
this._refreshSigner();
|
|
1429
|
-
return receipt;
|
|
1512
|
+
const safe7579Iface = new ethers2.Interface(SAFE7579_ACCOUNT_ABI);
|
|
1513
|
+
const callData = safe7579Iface.encodeFunctionData("execute", [MODE_BATCH, executionCalldata]);
|
|
1514
|
+
return this._submitUserOp(callData);
|
|
1430
1515
|
}
|
|
1431
1516
|
/** Convert MorphoMarketParams to Solidity tuple. */
|
|
1432
1517
|
_toTuple(p) {
|
|
@@ -1793,14 +1878,14 @@ var ScoringClient = class {
|
|
|
1793
1878
|
}
|
|
1794
1879
|
}
|
|
1795
1880
|
// ════════════════════════════════════════════════════════
|
|
1796
|
-
// Score (x402-gated — computes & submits
|
|
1881
|
+
// Score (x402-gated — computes & submits onchain)
|
|
1797
1882
|
// ════════════════════════════════════════════════════════
|
|
1798
1883
|
/**
|
|
1799
1884
|
* Request a fresh score computation.
|
|
1800
1885
|
*
|
|
1801
1886
|
* This is x402-gated: the backend returns 402, the X402Client
|
|
1802
1887
|
* signs an EIP-3009 payment, and the backend computes + submits
|
|
1803
|
-
* the score
|
|
1888
|
+
* the score onchain via AgentReputation.submitScore().
|
|
1804
1889
|
*
|
|
1805
1890
|
* Returns the ScoreResult with breakdown and txHash.
|
|
1806
1891
|
*/
|
|
@@ -1824,10 +1909,10 @@ var ScoringClient = class {
|
|
|
1824
1909
|
return result.data;
|
|
1825
1910
|
}
|
|
1826
1911
|
// ════════════════════════════════════════════════════════
|
|
1827
|
-
// Current Score (free — reads
|
|
1912
|
+
// Current Score (free — reads onchain)
|
|
1828
1913
|
// ════════════════════════════════════════════════════════
|
|
1829
1914
|
/**
|
|
1830
|
-
* Get the current
|
|
1915
|
+
* Get the current onchain score (free, no payment required).
|
|
1831
1916
|
*/
|
|
1832
1917
|
async getCurrentScore(agentId) {
|
|
1833
1918
|
const response = await this.client.get(`/score/${agentId.toString()}/current`);
|
|
@@ -1976,7 +2061,7 @@ var AgentIdentityClient = class {
|
|
|
1976
2061
|
return { ...result, existing: false };
|
|
1977
2062
|
}
|
|
1978
2063
|
/**
|
|
1979
|
-
* Register agent with URI and
|
|
2064
|
+
* Register agent with URI and onchain metadata
|
|
1980
2065
|
*/
|
|
1981
2066
|
async registerWithMetadata(agentURI, metadata) {
|
|
1982
2067
|
const metadataEntries = metadata.map((m) => ({
|
|
@@ -2012,7 +2097,7 @@ var AgentIdentityClient = class {
|
|
|
2012
2097
|
return receipt.hash;
|
|
2013
2098
|
}
|
|
2014
2099
|
/**
|
|
2015
|
-
* Set
|
|
2100
|
+
* Set onchain metadata (key-value)
|
|
2016
2101
|
*/
|
|
2017
2102
|
async setMetadata(agentId, key, value) {
|
|
2018
2103
|
const tx = await this.identityRegistry.setMetadata(
|
|
@@ -2024,7 +2109,7 @@ var AgentIdentityClient = class {
|
|
|
2024
2109
|
return receipt.hash;
|
|
2025
2110
|
}
|
|
2026
2111
|
/**
|
|
2027
|
-
* Get
|
|
2112
|
+
* Get onchain metadata
|
|
2028
2113
|
*/
|
|
2029
2114
|
async getMetadata(agentId, key) {
|
|
2030
2115
|
const value = await this.identityRegistry.getMetadata(agentId, key);
|
|
@@ -2252,19 +2337,26 @@ function rateToBps(rate) {
|
|
|
2252
2337
|
}
|
|
2253
2338
|
export {
|
|
2254
2339
|
ACCOUNT_FACTORY_ABI,
|
|
2255
|
-
AGENT_ACCOUNT_ABI,
|
|
2256
2340
|
AGENT_REPUTATION_ABI,
|
|
2341
|
+
AGETHER_4337_FACTORY_ABI,
|
|
2342
|
+
AGETHER_8004_SCORER_ABI,
|
|
2343
|
+
AGETHER_8004_VALIDATION_MODULE_ABI,
|
|
2344
|
+
AGETHER_HOOK_MULTIPLEXER_ABI,
|
|
2257
2345
|
AgentIdentityClient,
|
|
2258
2346
|
AgentNotApprovedError,
|
|
2259
2347
|
AgetherClient,
|
|
2260
2348
|
AgetherError,
|
|
2261
2349
|
ChainId,
|
|
2350
|
+
ENTRYPOINT_V07_ABI,
|
|
2262
2351
|
ERC20_ABI,
|
|
2352
|
+
ERC8004_VALIDATION_MODULE_ABI,
|
|
2353
|
+
HOOK_MULTIPLEXER_ABI,
|
|
2263
2354
|
IDENTITY_REGISTRY_ABI,
|
|
2264
2355
|
InsufficientBalanceError,
|
|
2265
|
-
KYA_HOOK_ABI,
|
|
2266
2356
|
MORPHO_BLUE_ABI,
|
|
2267
2357
|
MorphoClient,
|
|
2358
|
+
SAFE7579_ACCOUNT_ABI,
|
|
2359
|
+
SAFE_AGENT_FACTORY_ABI,
|
|
2268
2360
|
ScoringClient,
|
|
2269
2361
|
ScoringRejectedError,
|
|
2270
2362
|
VALIDATION_REGISTRY_ABI,
|