@owney/sdk 0.7.5 → 0.7.6
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.cjs +78 -6
- package/dist/index.js +80 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -825,6 +825,9 @@ function debugLog(scope, message, data) {
|
|
|
825
825
|
}
|
|
826
826
|
|
|
827
827
|
// src/agents/zyfai/zyfai.agent.ts
|
|
828
|
+
var ERC7579_IS_MODULE_INSTALLED_ABI = (0, import_viem.parseAbi)([
|
|
829
|
+
"function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)"
|
|
830
|
+
]);
|
|
828
831
|
var DEFAULT_ZYFAI_RPC_URLS = {
|
|
829
832
|
8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
830
833
|
42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
@@ -1142,7 +1145,12 @@ var ZyfaiAgent = class {
|
|
|
1142
1145
|
const validChainId = isValidChainId(chainId);
|
|
1143
1146
|
await Promise.all([
|
|
1144
1147
|
this.ensureProtocolsSynced(validChainId, "USDC"),
|
|
1145
|
-
this.ensureProtocolsSynced(validChainId, "WETH")
|
|
1148
|
+
this.ensureProtocolsSynced(validChainId, "WETH"),
|
|
1149
|
+
// Retrofit a session key for old wallets that are already deployed and
|
|
1150
|
+
// funded but never got one — otherwise their balance stays idle until
|
|
1151
|
+
// they happen to deposit again. Only touches Safes that are missing the
|
|
1152
|
+
// validator, so pool-wallet users see no prompt. Non-fatal.
|
|
1153
|
+
this.ensureSessionKeyIfDeployed(validChainId)
|
|
1146
1154
|
]);
|
|
1147
1155
|
} catch (error) {
|
|
1148
1156
|
throw error;
|
|
@@ -1340,6 +1348,65 @@ var ZyfaiAgent = class {
|
|
|
1340
1348
|
return false;
|
|
1341
1349
|
}
|
|
1342
1350
|
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Ensure Zyfai's automation can actually act on the user's Safe for this
|
|
1353
|
+
* chain, by making sure a session key exists.
|
|
1354
|
+
*
|
|
1355
|
+
* Old wallets (pre-0.2.44) are deployed WITHOUT the smart-sessions validator,
|
|
1356
|
+
* so Zyfai's rebalancer has no authorised path to move funds: deposits land
|
|
1357
|
+
* and then sit as raw tokens forever. Pre-deployed pool wallets ship with the
|
|
1358
|
+
* module already installed, which is why they never needed this.
|
|
1359
|
+
*
|
|
1360
|
+
* The gate is the on-chain module, not the wallet's class: it is the exact
|
|
1361
|
+
* condition that matters, it needs no guessing from API shapes, and it means
|
|
1362
|
+
* pool-wallet users are never prompted for a signature they don't need.
|
|
1363
|
+
*
|
|
1364
|
+
* Non-fatal by design. A failure here must not block a deposit — the funds
|
|
1365
|
+
* still arrive safely in the Safe, they just won't be deployed into a pool
|
|
1366
|
+
* until a session key exists.
|
|
1367
|
+
*/
|
|
1368
|
+
/**
|
|
1369
|
+
* Activation-time variant: only acts when the Safe already has code on this
|
|
1370
|
+
* chain. Activation must never deploy anything — that is deposit's job, and it
|
|
1371
|
+
* would mean surprise on-chain work just for opening the app.
|
|
1372
|
+
*/
|
|
1373
|
+
async ensureSessionKeyIfDeployed(chainId) {
|
|
1374
|
+
try {
|
|
1375
|
+
const ownerAddress = this.getAddress();
|
|
1376
|
+
const wallet = await this.sdk.getSmartWalletAddress(
|
|
1377
|
+
ownerAddress,
|
|
1378
|
+
chainId
|
|
1379
|
+
);
|
|
1380
|
+
if (!wallet.isDeployed) return;
|
|
1381
|
+
await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
|
|
1382
|
+
} catch (error) {
|
|
1383
|
+
console.warn(
|
|
1384
|
+
"[zyfai] session-key check at activation failed (non-fatal):",
|
|
1385
|
+
error instanceof Error ? error.message : String(error)
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
async ensureSessionKey(ownerAddress, chainId, smartWallet) {
|
|
1390
|
+
try {
|
|
1391
|
+
const installed = await this.getPublicClient(chainId).readContract({
|
|
1392
|
+
address: smartWallet,
|
|
1393
|
+
abi: ERC7579_IS_MODULE_INSTALLED_ABI,
|
|
1394
|
+
functionName: "isModuleInstalled",
|
|
1395
|
+
// moduleTypeId 1 = validator (ERC-7579)
|
|
1396
|
+
args: [1n, import_sdk.SMART_SESSIONS_VALIDATOR, "0x"]
|
|
1397
|
+
});
|
|
1398
|
+
if (installed) return;
|
|
1399
|
+
console.warn(
|
|
1400
|
+
`[zyfai] Safe ${smartWallet} has no smart-sessions validator on chain ${chainId}; creating a session key so the agent can allocate.`
|
|
1401
|
+
);
|
|
1402
|
+
await this.sdk.createSessionKey(ownerAddress, chainId);
|
|
1403
|
+
} catch (error) {
|
|
1404
|
+
console.warn(
|
|
1405
|
+
"[zyfai] createSessionKey skipped (non-fatal):",
|
|
1406
|
+
error instanceof Error ? error.message : String(error)
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1343
1410
|
/**
|
|
1344
1411
|
* Guarantee the user's Safe has code on `chainId` before anything transfers
|
|
1345
1412
|
* funds into it, and return its address.
|
|
@@ -1360,17 +1427,21 @@ var ZyfaiAgent = class {
|
|
|
1360
1427
|
*/
|
|
1361
1428
|
async ensureWalletDeployed(ownerAddress, chainId) {
|
|
1362
1429
|
const wallet = await this.sdk.getSmartWalletAddress(ownerAddress, chainId);
|
|
1363
|
-
if (wallet.isDeployed)
|
|
1430
|
+
if (wallet.isDeployed) {
|
|
1431
|
+
await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
|
|
1432
|
+
return wallet.address;
|
|
1433
|
+
}
|
|
1364
1434
|
const poolFirst = await this.isPredeployedPoolWallet(
|
|
1365
1435
|
ownerAddress,
|
|
1366
1436
|
wallet.address
|
|
1367
1437
|
);
|
|
1368
1438
|
const deployAsPool = () => this.sdk.deployOnChains([chainId]);
|
|
1369
1439
|
const deployAsLegacy = () => (
|
|
1370
|
-
// `createSessionKey:
|
|
1371
|
-
//
|
|
1372
|
-
//
|
|
1373
|
-
|
|
1440
|
+
// `createSessionKey: true` — per Zyfai, the old-wallet flow is
|
|
1441
|
+
// deploySafe(true) -> createSessionKey() -> deposit. Passing false (which
|
|
1442
|
+
// this did originally) deploys a Safe with no smart-sessions validator, so
|
|
1443
|
+
// deposits land and are never allocated into a pool.
|
|
1444
|
+
this.sdk.deploySafe(ownerAddress, chainId, "aggressive", true)
|
|
1374
1445
|
);
|
|
1375
1446
|
const [first, second] = poolFirst ? [deployAsPool, deployAsLegacy] : [deployAsLegacy, deployAsPool];
|
|
1376
1447
|
try {
|
|
@@ -1394,6 +1465,7 @@ var ZyfaiAgent = class {
|
|
|
1394
1465
|
this.id
|
|
1395
1466
|
);
|
|
1396
1467
|
}
|
|
1468
|
+
await this.ensureSessionKey(ownerAddress, chainId, redeployed.address);
|
|
1397
1469
|
return redeployed.address;
|
|
1398
1470
|
}
|
|
1399
1471
|
async deposit(state, chainId, amount, asset, depositCallback) {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/agents/zyfai/zyfai.agent.ts
|
|
2
|
-
import { ZyfaiSDK } from "@zyfai/sdk";
|
|
3
|
-
import { createPublicClient, http } from "viem";
|
|
2
|
+
import { SMART_SESSIONS_VALIDATOR, ZyfaiSDK } from "@zyfai/sdk";
|
|
3
|
+
import { createPublicClient, http, parseAbi } from "viem";
|
|
4
4
|
import { base, arbitrum, mainnet } from "viem/chains";
|
|
5
5
|
|
|
6
6
|
// src/types/config.ts
|
|
@@ -792,6 +792,9 @@ function debugLog(scope, message, data) {
|
|
|
792
792
|
}
|
|
793
793
|
|
|
794
794
|
// src/agents/zyfai/zyfai.agent.ts
|
|
795
|
+
var ERC7579_IS_MODULE_INSTALLED_ABI = parseAbi([
|
|
796
|
+
"function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)"
|
|
797
|
+
]);
|
|
795
798
|
var DEFAULT_ZYFAI_RPC_URLS = {
|
|
796
799
|
8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
797
800
|
42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
@@ -1109,7 +1112,12 @@ var ZyfaiAgent = class {
|
|
|
1109
1112
|
const validChainId = isValidChainId(chainId);
|
|
1110
1113
|
await Promise.all([
|
|
1111
1114
|
this.ensureProtocolsSynced(validChainId, "USDC"),
|
|
1112
|
-
this.ensureProtocolsSynced(validChainId, "WETH")
|
|
1115
|
+
this.ensureProtocolsSynced(validChainId, "WETH"),
|
|
1116
|
+
// Retrofit a session key for old wallets that are already deployed and
|
|
1117
|
+
// funded but never got one — otherwise their balance stays idle until
|
|
1118
|
+
// they happen to deposit again. Only touches Safes that are missing the
|
|
1119
|
+
// validator, so pool-wallet users see no prompt. Non-fatal.
|
|
1120
|
+
this.ensureSessionKeyIfDeployed(validChainId)
|
|
1113
1121
|
]);
|
|
1114
1122
|
} catch (error) {
|
|
1115
1123
|
throw error;
|
|
@@ -1307,6 +1315,65 @@ var ZyfaiAgent = class {
|
|
|
1307
1315
|
return false;
|
|
1308
1316
|
}
|
|
1309
1317
|
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Ensure Zyfai's automation can actually act on the user's Safe for this
|
|
1320
|
+
* chain, by making sure a session key exists.
|
|
1321
|
+
*
|
|
1322
|
+
* Old wallets (pre-0.2.44) are deployed WITHOUT the smart-sessions validator,
|
|
1323
|
+
* so Zyfai's rebalancer has no authorised path to move funds: deposits land
|
|
1324
|
+
* and then sit as raw tokens forever. Pre-deployed pool wallets ship with the
|
|
1325
|
+
* module already installed, which is why they never needed this.
|
|
1326
|
+
*
|
|
1327
|
+
* The gate is the on-chain module, not the wallet's class: it is the exact
|
|
1328
|
+
* condition that matters, it needs no guessing from API shapes, and it means
|
|
1329
|
+
* pool-wallet users are never prompted for a signature they don't need.
|
|
1330
|
+
*
|
|
1331
|
+
* Non-fatal by design. A failure here must not block a deposit — the funds
|
|
1332
|
+
* still arrive safely in the Safe, they just won't be deployed into a pool
|
|
1333
|
+
* until a session key exists.
|
|
1334
|
+
*/
|
|
1335
|
+
/**
|
|
1336
|
+
* Activation-time variant: only acts when the Safe already has code on this
|
|
1337
|
+
* chain. Activation must never deploy anything — that is deposit's job, and it
|
|
1338
|
+
* would mean surprise on-chain work just for opening the app.
|
|
1339
|
+
*/
|
|
1340
|
+
async ensureSessionKeyIfDeployed(chainId) {
|
|
1341
|
+
try {
|
|
1342
|
+
const ownerAddress = this.getAddress();
|
|
1343
|
+
const wallet = await this.sdk.getSmartWalletAddress(
|
|
1344
|
+
ownerAddress,
|
|
1345
|
+
chainId
|
|
1346
|
+
);
|
|
1347
|
+
if (!wallet.isDeployed) return;
|
|
1348
|
+
await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
|
|
1349
|
+
} catch (error) {
|
|
1350
|
+
console.warn(
|
|
1351
|
+
"[zyfai] session-key check at activation failed (non-fatal):",
|
|
1352
|
+
error instanceof Error ? error.message : String(error)
|
|
1353
|
+
);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
async ensureSessionKey(ownerAddress, chainId, smartWallet) {
|
|
1357
|
+
try {
|
|
1358
|
+
const installed = await this.getPublicClient(chainId).readContract({
|
|
1359
|
+
address: smartWallet,
|
|
1360
|
+
abi: ERC7579_IS_MODULE_INSTALLED_ABI,
|
|
1361
|
+
functionName: "isModuleInstalled",
|
|
1362
|
+
// moduleTypeId 1 = validator (ERC-7579)
|
|
1363
|
+
args: [1n, SMART_SESSIONS_VALIDATOR, "0x"]
|
|
1364
|
+
});
|
|
1365
|
+
if (installed) return;
|
|
1366
|
+
console.warn(
|
|
1367
|
+
`[zyfai] Safe ${smartWallet} has no smart-sessions validator on chain ${chainId}; creating a session key so the agent can allocate.`
|
|
1368
|
+
);
|
|
1369
|
+
await this.sdk.createSessionKey(ownerAddress, chainId);
|
|
1370
|
+
} catch (error) {
|
|
1371
|
+
console.warn(
|
|
1372
|
+
"[zyfai] createSessionKey skipped (non-fatal):",
|
|
1373
|
+
error instanceof Error ? error.message : String(error)
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1310
1377
|
/**
|
|
1311
1378
|
* Guarantee the user's Safe has code on `chainId` before anything transfers
|
|
1312
1379
|
* funds into it, and return its address.
|
|
@@ -1327,17 +1394,21 @@ var ZyfaiAgent = class {
|
|
|
1327
1394
|
*/
|
|
1328
1395
|
async ensureWalletDeployed(ownerAddress, chainId) {
|
|
1329
1396
|
const wallet = await this.sdk.getSmartWalletAddress(ownerAddress, chainId);
|
|
1330
|
-
if (wallet.isDeployed)
|
|
1397
|
+
if (wallet.isDeployed) {
|
|
1398
|
+
await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
|
|
1399
|
+
return wallet.address;
|
|
1400
|
+
}
|
|
1331
1401
|
const poolFirst = await this.isPredeployedPoolWallet(
|
|
1332
1402
|
ownerAddress,
|
|
1333
1403
|
wallet.address
|
|
1334
1404
|
);
|
|
1335
1405
|
const deployAsPool = () => this.sdk.deployOnChains([chainId]);
|
|
1336
1406
|
const deployAsLegacy = () => (
|
|
1337
|
-
// `createSessionKey:
|
|
1338
|
-
//
|
|
1339
|
-
//
|
|
1340
|
-
|
|
1407
|
+
// `createSessionKey: true` — per Zyfai, the old-wallet flow is
|
|
1408
|
+
// deploySafe(true) -> createSessionKey() -> deposit. Passing false (which
|
|
1409
|
+
// this did originally) deploys a Safe with no smart-sessions validator, so
|
|
1410
|
+
// deposits land and are never allocated into a pool.
|
|
1411
|
+
this.sdk.deploySafe(ownerAddress, chainId, "aggressive", true)
|
|
1341
1412
|
);
|
|
1342
1413
|
const [first, second] = poolFirst ? [deployAsPool, deployAsLegacy] : [deployAsLegacy, deployAsPool];
|
|
1343
1414
|
try {
|
|
@@ -1361,6 +1432,7 @@ var ZyfaiAgent = class {
|
|
|
1361
1432
|
this.id
|
|
1362
1433
|
);
|
|
1363
1434
|
}
|
|
1435
|
+
await this.ensureSessionKey(ownerAddress, chainId, redeployed.address);
|
|
1364
1436
|
return redeployed.address;
|
|
1365
1437
|
}
|
|
1366
1438
|
async deposit(state, chainId, amount, asset, depositCallback) {
|