@agether/sdk 1.11.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +195 -114
- package/dist/index.d.mts +77 -32
- package/dist/index.d.ts +77 -32
- package/dist/index.js +245 -157
- package/dist/index.mjs +240 -155
- package/package.json +1 -1
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,
|
|
50
|
+
var IDENTITY_REGISTRY_ABI, SAFE_AGENT_FACTORY_ABI, ACCOUNT_FACTORY_ABI, ERC8004_VALIDATION_MODULE_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,38 +59,34 @@ 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
|
-
|
|
62
|
+
SAFE_AGENT_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
|
|
69
|
-
"function
|
|
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
|
-
"
|
|
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
|
+
"function SENTINEL_OWNER() view returns (address)",
|
|
77
|
+
"event AccountCreated(uint256 indexed agentId, address indexed safeAccount, address indexed owner)"
|
|
72
78
|
];
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
ACCOUNT_FACTORY_ABI = SAFE_AGENT_FACTORY_ABI;
|
|
80
|
+
ERC8004_VALIDATION_MODULE_ABI = [
|
|
81
|
+
// View
|
|
82
|
+
"function getConfig(address account) view returns (address registry, uint256 agentId)",
|
|
83
|
+
"function getOwner(address account) view returns (address)",
|
|
84
|
+
"function isInstalled(address account) view returns (bool)",
|
|
85
|
+
"function isKYAApproved(address account) view returns (bool)",
|
|
86
|
+
"function validationRegistry() view returns (address)",
|
|
75
87
|
"function owner() view returns (address)",
|
|
76
|
-
|
|
77
|
-
"function
|
|
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)"
|
|
88
|
+
// Admin (via TimelockController)
|
|
89
|
+
"function setValidationRegistry(address registry_)"
|
|
94
90
|
];
|
|
95
91
|
AGENT_REPUTATION_ABI = [
|
|
96
92
|
"function getCreditScore(uint256 agentId) view returns (uint256)",
|
|
@@ -130,9 +126,22 @@ var init_abis = __esm({
|
|
|
130
126
|
"function symbol() view returns (string)",
|
|
131
127
|
"function name() view returns (string)"
|
|
132
128
|
];
|
|
133
|
-
|
|
134
|
-
"function
|
|
135
|
-
"function
|
|
129
|
+
ENTRYPOINT_V07_ABI = [
|
|
130
|
+
"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)",
|
|
131
|
+
"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)",
|
|
132
|
+
"function getNonce(address sender, uint192 key) view returns (uint256 nonce)",
|
|
133
|
+
"function balanceOf(address account) view returns (uint256)",
|
|
134
|
+
"function depositTo(address account) payable",
|
|
135
|
+
"event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed)"
|
|
136
|
+
];
|
|
137
|
+
SAFE7579_ACCOUNT_ABI = [
|
|
138
|
+
// ERC-7579 execution (called via UserOp through Safe7579 fallback)
|
|
139
|
+
"function execute(bytes32 mode, bytes executionCalldata) payable",
|
|
140
|
+
"function executeFromExecutor(bytes32 mode, bytes executionCalldata) payable returns (bytes[])",
|
|
141
|
+
// ERC-7579 module queries
|
|
142
|
+
"function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)",
|
|
143
|
+
// EIP-1271
|
|
144
|
+
"function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)"
|
|
136
145
|
];
|
|
137
146
|
}
|
|
138
147
|
});
|
|
@@ -146,56 +155,99 @@ function getDefaultConfig(chainId) {
|
|
|
146
155
|
scoringEndpoint: SCORING_ENDPOINTS[chainId]
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
|
-
var CONTRACT_ADDRESSES, RPC_URLS, SCORING_ENDPOINTS;
|
|
158
|
+
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
159
|
var init_config = __esm({
|
|
151
160
|
"src/utils/config.ts"() {
|
|
152
161
|
"use strict";
|
|
153
162
|
init_types();
|
|
163
|
+
ZERO = "0x0000000000000000000000000000000000000000";
|
|
164
|
+
ENTRYPOINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
|
|
165
|
+
ERC8004_IDENTITY_REGISTRY = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
|
|
166
|
+
ERC8004_IDENTITY_REGISTRY_TESTNET = "0x8004A818BFB912233c491871b3d84c89A494BD9e";
|
|
167
|
+
MORPHO_BLUE = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb";
|
|
168
|
+
SAFE_SINGLETON = "0x41675C099F32341bf84BFc5382aF534df5C7461a";
|
|
169
|
+
SAFE_PROXY_FACTORY = "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67";
|
|
170
|
+
SAFE7579 = "0x7579EE8307284F293B1927136486880611F20002";
|
|
154
171
|
CONTRACT_ADDRESSES = {
|
|
155
172
|
[1 /* Ethereum */]: {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
173
|
+
safeSingleton: SAFE_SINGLETON,
|
|
174
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
175
|
+
safe7579: SAFE7579,
|
|
176
|
+
entryPoint: ENTRYPOINT_V07,
|
|
177
|
+
safeAgentFactory: ZERO,
|
|
178
|
+
safe7579Bootstrap: ZERO,
|
|
179
|
+
erc8004ValidationModule: ZERO,
|
|
180
|
+
hookMultiplexer: ZERO,
|
|
181
|
+
validationRegistry: ZERO,
|
|
182
|
+
agentReputation: ZERO,
|
|
183
|
+
timelockController: ZERO,
|
|
160
184
|
usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
161
|
-
identityRegistry:
|
|
162
|
-
morphoBlue:
|
|
185
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY,
|
|
186
|
+
morphoBlue: MORPHO_BLUE
|
|
163
187
|
},
|
|
164
188
|
[8453 /* Base */]: {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
189
|
+
safeSingleton: SAFE_SINGLETON,
|
|
190
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
191
|
+
safe7579: SAFE7579,
|
|
192
|
+
entryPoint: ENTRYPOINT_V07,
|
|
193
|
+
safeAgentFactory: "0xB0A88ffe28491E793F7706829278f20d724947d1",
|
|
194
|
+
safe7579Bootstrap: "0x72A636bc23B2644138489c3bBE3B05a0a7184b33",
|
|
195
|
+
erc8004ValidationModule: "0x49e27A6B4d012B87271897b51d0296ABcFCb0BBd",
|
|
196
|
+
hookMultiplexer: "0x12c77f17F91f06a11C2C34C618ce9d78f9a34541",
|
|
197
|
+
validationRegistry: "0x88E21e8883c093E4c8d0d0cE68f1c93Cf6190f51",
|
|
198
|
+
agentReputation: "0x4C2d42cbD35f6541f0902499CFEC27C1Cf5683E3",
|
|
199
|
+
timelockController: "0x0517b4f73b61774C88A2B1c5745141315E831015",
|
|
169
200
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
170
|
-
identityRegistry:
|
|
171
|
-
morphoBlue:
|
|
201
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY,
|
|
202
|
+
morphoBlue: MORPHO_BLUE
|
|
172
203
|
},
|
|
173
204
|
[84532 /* BaseSepolia */]: {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
205
|
+
safeSingleton: SAFE_SINGLETON,
|
|
206
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
207
|
+
safe7579: SAFE7579,
|
|
208
|
+
entryPoint: ENTRYPOINT_V07,
|
|
209
|
+
safeAgentFactory: ZERO,
|
|
210
|
+
safe7579Bootstrap: ZERO,
|
|
211
|
+
erc8004ValidationModule: ZERO,
|
|
212
|
+
hookMultiplexer: ZERO,
|
|
213
|
+
validationRegistry: ZERO,
|
|
214
|
+
agentReputation: ZERO,
|
|
215
|
+
timelockController: ZERO,
|
|
178
216
|
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
179
|
-
identityRegistry:
|
|
180
|
-
morphoBlue:
|
|
217
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
|
|
218
|
+
morphoBlue: ZERO
|
|
181
219
|
},
|
|
182
220
|
[11155111 /* Sepolia */]: {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
221
|
+
safeSingleton: SAFE_SINGLETON,
|
|
222
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
223
|
+
safe7579: SAFE7579,
|
|
224
|
+
entryPoint: ENTRYPOINT_V07,
|
|
225
|
+
safeAgentFactory: ZERO,
|
|
226
|
+
safe7579Bootstrap: ZERO,
|
|
227
|
+
erc8004ValidationModule: ZERO,
|
|
228
|
+
hookMultiplexer: ZERO,
|
|
229
|
+
validationRegistry: ZERO,
|
|
230
|
+
agentReputation: ZERO,
|
|
231
|
+
timelockController: ZERO,
|
|
187
232
|
usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
188
|
-
identityRegistry:
|
|
189
|
-
morphoBlue:
|
|
233
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY_TESTNET,
|
|
234
|
+
morphoBlue: ZERO
|
|
190
235
|
},
|
|
191
236
|
[31337 /* Hardhat */]: {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
237
|
+
safeSingleton: SAFE_SINGLETON,
|
|
238
|
+
safeProxyFactory: SAFE_PROXY_FACTORY,
|
|
239
|
+
safe7579: SAFE7579,
|
|
240
|
+
entryPoint: ENTRYPOINT_V07,
|
|
241
|
+
safeAgentFactory: ZERO,
|
|
242
|
+
safe7579Bootstrap: ZERO,
|
|
243
|
+
erc8004ValidationModule: ZERO,
|
|
244
|
+
hookMultiplexer: ZERO,
|
|
245
|
+
validationRegistry: ZERO,
|
|
246
|
+
agentReputation: ZERO,
|
|
247
|
+
timelockController: ZERO,
|
|
196
248
|
usdc: "0x56d4d6aEe0278c5Df2FA23Ecb32eC146C9446FDf",
|
|
197
|
-
identityRegistry:
|
|
198
|
-
morphoBlue:
|
|
249
|
+
identityRegistry: ERC8004_IDENTITY_REGISTRY,
|
|
250
|
+
morphoBlue: ZERO
|
|
199
251
|
}
|
|
200
252
|
};
|
|
201
253
|
RPC_URLS = {
|
|
@@ -270,27 +322,24 @@ var init_MorphoClient = __esm({
|
|
|
270
322
|
this._eoaAddress = wallet.address;
|
|
271
323
|
}
|
|
272
324
|
const addrs = { ...defaultCfg.contracts, ...config.contracts };
|
|
273
|
-
this.
|
|
325
|
+
this.safeAgentFactory = new import_ethers.Contract(addrs.safeAgentFactory, ACCOUNT_FACTORY_ABI, this._signer);
|
|
274
326
|
this.morphoBlue = new import_ethers.Contract(addrs.morphoBlue, MORPHO_BLUE_ABI, this.provider);
|
|
275
327
|
this.agentReputation = new import_ethers.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
|
|
276
328
|
this.identityRegistry = new import_ethers.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
|
|
329
|
+
this.entryPoint = new import_ethers.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
|
|
330
|
+
this.validationModule = new import_ethers.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
|
|
277
331
|
}
|
|
278
332
|
// ════════════════════════════════════════════════════════
|
|
279
333
|
// KYA Gate Check
|
|
280
334
|
// ════════════════════════════════════════════════════════
|
|
281
335
|
/**
|
|
282
336
|
* Check whether the KYA (Know Your Agent) code verification gate is active.
|
|
283
|
-
* Reads the
|
|
284
|
-
*
|
|
337
|
+
* Reads the ERC8004ValidationModule's validationRegistry — when set to
|
|
338
|
+
* a non-zero address, the module enforces KYA code approval.
|
|
285
339
|
*/
|
|
286
340
|
async isKyaRequired() {
|
|
287
341
|
try {
|
|
288
|
-
const
|
|
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();
|
|
342
|
+
const registryAddr = await this.validationModule.validationRegistry();
|
|
294
343
|
return registryAddr !== import_ethers.ethers.ZeroAddress;
|
|
295
344
|
} catch {
|
|
296
345
|
return false;
|
|
@@ -307,7 +356,7 @@ var init_MorphoClient = __esm({
|
|
|
307
356
|
let lastErr;
|
|
308
357
|
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
309
358
|
try {
|
|
310
|
-
const addr = await this.
|
|
359
|
+
const addr = await this.safeAgentFactory.getAccount(BigInt(this.agentId));
|
|
311
360
|
if (addr === import_ethers.ethers.ZeroAddress) {
|
|
312
361
|
throw new AgetherError("No AgentAccount found. Call register() first.", "NO_ACCOUNT");
|
|
313
362
|
}
|
|
@@ -385,9 +434,9 @@ var init_MorphoClient = __esm({
|
|
|
385
434
|
async register(_name) {
|
|
386
435
|
const eoaAddr = await this.getSignerAddress();
|
|
387
436
|
if (this.agentId) {
|
|
388
|
-
const exists = await this.
|
|
437
|
+
const exists = await this.safeAgentFactory.accountExists(BigInt(this.agentId));
|
|
389
438
|
if (exists) {
|
|
390
|
-
const acct = await this.
|
|
439
|
+
const acct = await this.safeAgentFactory.getAccount(BigInt(this.agentId));
|
|
391
440
|
this._accountAddress = acct;
|
|
392
441
|
const kyaRequired2 = await this.isKyaRequired();
|
|
393
442
|
return { agentId: this.agentId, address: eoaAddr, agentAccount: acct, alreadyRegistered: true, kyaRequired: kyaRequired2 };
|
|
@@ -405,15 +454,15 @@ var init_MorphoClient = __esm({
|
|
|
405
454
|
agentId = await this._mintNewIdentity();
|
|
406
455
|
}
|
|
407
456
|
this.agentId = agentId.toString();
|
|
408
|
-
const acctExists = await this.
|
|
457
|
+
const acctExists = await this.safeAgentFactory.accountExists(agentId);
|
|
409
458
|
let txHash;
|
|
410
459
|
if (!acctExists) {
|
|
411
|
-
const tx = await this.
|
|
460
|
+
const tx = await this.safeAgentFactory.createAccount(agentId);
|
|
412
461
|
const receipt = await tx.wait();
|
|
413
462
|
this._refreshSigner();
|
|
414
463
|
txHash = receipt.hash;
|
|
415
464
|
}
|
|
416
|
-
const acctAddr = await this.
|
|
465
|
+
const acctAddr = await this.safeAgentFactory.getAccount(agentId);
|
|
417
466
|
this._accountAddress = acctAddr;
|
|
418
467
|
const kyaRequired = await this.isKyaRequired();
|
|
419
468
|
return {
|
|
@@ -1140,7 +1189,7 @@ var init_MorphoClient = __esm({
|
|
|
1140
1189
|
if (target.address) {
|
|
1141
1190
|
targetAddr = target.address;
|
|
1142
1191
|
} else if (target.agentId) {
|
|
1143
|
-
targetAddr = await this.
|
|
1192
|
+
targetAddr = await this.safeAgentFactory.getAccount(BigInt(target.agentId));
|
|
1144
1193
|
if (targetAddr === import_ethers.ethers.ZeroAddress) throw new AgetherError("Target agent has no account", "NO_ACCOUNT");
|
|
1145
1194
|
} else {
|
|
1146
1195
|
throw new AgetherError("Provide agentId or address", "INVALID_TARGET");
|
|
@@ -1193,7 +1242,9 @@ var init_MorphoClient = __esm({
|
|
|
1193
1242
|
_refreshSigner() {
|
|
1194
1243
|
if (this._useExternalSigner) {
|
|
1195
1244
|
const addrs = this.config.contracts;
|
|
1196
|
-
this.
|
|
1245
|
+
this.safeAgentFactory = new import_ethers.Contract(addrs.safeAgentFactory, ACCOUNT_FACTORY_ABI, this._signer);
|
|
1246
|
+
this.entryPoint = new import_ethers.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
|
|
1247
|
+
this.validationModule = new import_ethers.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
|
|
1197
1248
|
this.agentReputation = new import_ethers.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
|
|
1198
1249
|
this.identityRegistry = new import_ethers.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
|
|
1199
1250
|
} else {
|
|
@@ -1202,57 +1253,87 @@ var init_MorphoClient = __esm({
|
|
|
1202
1253
|
this._signer = wallet;
|
|
1203
1254
|
this._eoaAddress = wallet.address;
|
|
1204
1255
|
const addrs = this.config.contracts;
|
|
1205
|
-
this.
|
|
1256
|
+
this.safeAgentFactory = new import_ethers.Contract(addrs.safeAgentFactory, ACCOUNT_FACTORY_ABI, this._signer);
|
|
1257
|
+
this.entryPoint = new import_ethers.Contract(addrs.entryPoint, ENTRYPOINT_V07_ABI, this._signer);
|
|
1258
|
+
this.validationModule = new import_ethers.Contract(addrs.erc8004ValidationModule, ERC8004_VALIDATION_MODULE_ABI, this.provider);
|
|
1206
1259
|
this.agentReputation = new import_ethers.Contract(addrs.agentReputation, AGENT_REPUTATION_ABI, this._signer);
|
|
1207
1260
|
this.identityRegistry = new import_ethers.Contract(addrs.identityRegistry, IDENTITY_REGISTRY_ABI, this._signer);
|
|
1208
1261
|
}
|
|
1209
1262
|
}
|
|
1263
|
+
// ────────────────────────────────────────────────────────────
|
|
1264
|
+
// ERC-4337 UserOp helpers (Safe + Safe7579 + EntryPoint v0.7)
|
|
1265
|
+
// ────────────────────────────────────────────────────────────
|
|
1210
1266
|
/**
|
|
1211
|
-
*
|
|
1267
|
+
* Pack two uint128 values into a single bytes32:
|
|
1268
|
+
* bytes32 = (hi << 128) | lo
|
|
1269
|
+
*/
|
|
1270
|
+
_packUint128(hi, lo) {
|
|
1271
|
+
return import_ethers.ethers.zeroPadValue(import_ethers.ethers.toBeHex(hi << 128n | lo), 32);
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Build, sign and submit a PackedUserOperation through EntryPoint.handleOps.
|
|
1275
|
+
*
|
|
1276
|
+
* @param callData – the ABI-encoded calldata for the Safe7579 account
|
|
1277
|
+
* (e.g. `execute(mode, executionCalldata)`)
|
|
1278
|
+
* @returns the transaction receipt of the handleOps call
|
|
1279
|
+
*/
|
|
1280
|
+
async _submitUserOp(callData) {
|
|
1281
|
+
const sender = await this.getAccountAddress();
|
|
1282
|
+
const nonce = await this.entryPoint.getNonce(sender, 0);
|
|
1283
|
+
const feeData = await this.provider.getFeeData();
|
|
1284
|
+
const maxFeePerGas = feeData.maxFeePerGas ?? import_ethers.ethers.parseUnits("0.5", "gwei");
|
|
1285
|
+
const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? import_ethers.ethers.parseUnits("0.1", "gwei");
|
|
1286
|
+
const verificationGasLimit = 500000n;
|
|
1287
|
+
const callGasLimit = 800000n;
|
|
1288
|
+
const preVerificationGas = 100000n;
|
|
1289
|
+
const accountGasLimits = this._packUint128(verificationGasLimit, callGasLimit);
|
|
1290
|
+
const gasFees = this._packUint128(maxPriorityFeePerGas, maxFeePerGas);
|
|
1291
|
+
const userOp = {
|
|
1292
|
+
sender,
|
|
1293
|
+
nonce,
|
|
1294
|
+
initCode: "0x",
|
|
1295
|
+
callData,
|
|
1296
|
+
accountGasLimits,
|
|
1297
|
+
preVerificationGas,
|
|
1298
|
+
gasFees,
|
|
1299
|
+
paymasterAndData: "0x",
|
|
1300
|
+
signature: "0x"
|
|
1301
|
+
// placeholder — replaced after signing
|
|
1302
|
+
};
|
|
1303
|
+
const userOpHash = await this.entryPoint.getUserOpHash(userOp);
|
|
1304
|
+
const signature = await this._signer.signMessage(import_ethers.ethers.getBytes(userOpHash));
|
|
1305
|
+
userOp.signature = signature;
|
|
1306
|
+
const tx = await this.entryPoint.handleOps([userOp], await this.getSignerAddress());
|
|
1307
|
+
const receipt = await tx.wait();
|
|
1308
|
+
this._refreshSigner();
|
|
1309
|
+
return receipt;
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Execute a single call via Safe7579 account (ERC-7579 single mode)
|
|
1313
|
+
* through an ERC-4337 UserOperation.
|
|
1212
1314
|
*/
|
|
1213
1315
|
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
1316
|
const executionCalldata = import_ethers.ethers.AbiCoder.defaultAbiCoder().encode(
|
|
1217
1317
|
["address", "uint256", "bytes"],
|
|
1218
1318
|
[target, value, data]
|
|
1219
1319
|
);
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
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;
|
|
1320
|
+
const safe7579Iface = new import_ethers.ethers.Interface(SAFE7579_ACCOUNT_ABI);
|
|
1321
|
+
const callData = safe7579Iface.encodeFunctionData("execute", [MODE_SINGLE, executionCalldata]);
|
|
1322
|
+
return this._submitUserOp(callData);
|
|
1232
1323
|
}
|
|
1233
1324
|
/**
|
|
1234
|
-
* Execute multiple calls via
|
|
1325
|
+
* Execute multiple calls via Safe7579 account (ERC-7579 batch mode)
|
|
1326
|
+
* through an ERC-4337 UserOperation.
|
|
1235
1327
|
*/
|
|
1236
1328
|
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
1329
|
const executions = targets.map((t, i) => [t, values[i], datas[i]]);
|
|
1240
1330
|
const executionCalldata = import_ethers.ethers.AbiCoder.defaultAbiCoder().encode(
|
|
1241
1331
|
["(address,uint256,bytes)[]"],
|
|
1242
1332
|
[executions]
|
|
1243
1333
|
);
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
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;
|
|
1334
|
+
const safe7579Iface = new import_ethers.ethers.Interface(SAFE7579_ACCOUNT_ABI);
|
|
1335
|
+
const callData = safe7579Iface.encodeFunctionData("execute", [MODE_BATCH, executionCalldata]);
|
|
1336
|
+
return this._submitUserOp(callData);
|
|
1256
1337
|
}
|
|
1257
1338
|
/** Convert MorphoMarketParams to Solidity tuple. */
|
|
1258
1339
|
_toTuple(p) {
|
|
@@ -1753,10 +1834,10 @@ async function cmdRegister(name) {
|
|
|
1753
1834
|
process.exit(1);
|
|
1754
1835
|
}
|
|
1755
1836
|
const registryAddr = contracts.agentRegistry || contracts.identityRegistry;
|
|
1756
|
-
const factoryAddr = contracts.accountFactory;
|
|
1837
|
+
const factoryAddr = contracts.safeAgentFactory || contracts.accountFactory;
|
|
1757
1838
|
const validationAddr = contracts.validationRegistry;
|
|
1758
1839
|
if (!registryAddr || !factoryAddr) {
|
|
1759
|
-
console.error(" \u274C Backend missing agentRegistry or
|
|
1840
|
+
console.error(" \u274C Backend missing agentRegistry or safeAgentFactory");
|
|
1760
1841
|
process.exit(1);
|
|
1761
1842
|
}
|
|
1762
1843
|
console.log(" [2/4] Registering on ERC-8004 IdentityRegistry...");
|
|
@@ -1839,7 +1920,7 @@ async function cmdRegister(name) {
|
|
|
1839
1920
|
} else {
|
|
1840
1921
|
console.log(" [3/4] Skipping USDC mint (real network)");
|
|
1841
1922
|
}
|
|
1842
|
-
console.log(" [4/4] Creating
|
|
1923
|
+
console.log(" [4/4] Creating Safe account...");
|
|
1843
1924
|
if (factoryAddr) {
|
|
1844
1925
|
const factory = new import_ethers2.ethers.Contract(factoryAddr, ACCOUNT_FACTORY_ABI2, signer);
|
|
1845
1926
|
try {
|
|
@@ -2109,14 +2190,14 @@ async function cmdX402Call(url, method = "GET", body) {
|
|
|
2109
2190
|
}
|
|
2110
2191
|
function cmdHelp() {
|
|
2111
2192
|
console.log(`
|
|
2112
|
-
\u{1F3E6} Agether CLI \u2014 Direct Morpho Blue Credit for AI Agents
|
|
2193
|
+
\u{1F3E6} Agether CLI \u2014 Direct Morpho Blue Credit for AI Agents (Safe + Safe7579)
|
|
2113
2194
|
|
|
2114
2195
|
USAGE:
|
|
2115
2196
|
agether <command> [options]
|
|
2116
2197
|
|
|
2117
2198
|
SETUP:
|
|
2118
2199
|
init <private-key> [--agent-id <id>] Initialize with private key
|
|
2119
|
-
register [--name <n>] Register ERC-8004 + create
|
|
2200
|
+
register [--name <n>] Register ERC-8004 + create Safe account
|
|
2120
2201
|
|
|
2121
2202
|
INFO:
|
|
2122
2203
|
balance Check ETH + USDC balances
|
|
@@ -2132,7 +2213,7 @@ MORPHO LENDING:
|
|
|
2132
2213
|
repay --amount <usd> [--token <t>] Repay borrowed USDC
|
|
2133
2214
|
withdraw --amount <n> --token <t> Withdraw collateral (use 'all' for max)
|
|
2134
2215
|
sponsor --amount <n> --token <t> --agent-id <id> Send collateral to another agent
|
|
2135
|
-
fund --amount <usd> Transfer USDC from EOA to
|
|
2216
|
+
fund --amount <usd> Transfer USDC from EOA to Safe account
|
|
2136
2217
|
|
|
2137
2218
|
x402 PAYMENTS:
|
|
2138
2219
|
x402 <url> [--method GET|POST] [--body <json>] Make a paid API call
|