@owney/sdk 0.7.6 → 0.7.7-beta.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.cjs CHANGED
@@ -1336,7 +1336,43 @@ var ZyfaiAgent = class {
1336
1336
  * recoverable (ensureWalletDeployed tries the other deploy call), but
1337
1337
  * failing the deposit outright is not.
1338
1338
  */
1339
+ /**
1340
+ * Zyfai's own answer to "what kind of wallet is this, and can the agent act on
1341
+ * it", read from the positions payload (`GET /data/position`, which
1342
+ * `getPositions` wraps).
1343
+ *
1344
+ * `predeployed` and `hasActiveSessionKey` are both returned at runtime but
1345
+ * declared on neither `Portfolio` nor their docs, hence the cast. Verified
1346
+ * live: an old wallet reports `{predeployed: false, hasActiveSessionKey:
1347
+ * false}` while a pool wallet reports `{true, true}`.
1348
+ *
1349
+ * Preferred over the SDK's private `isPredeployed`, which is cached from the
1350
+ * login response and can go stale mid-session. Returns an empty object on any
1351
+ * failure so every caller degrades to its own fallback.
1352
+ */
1353
+ async readWalletState(ownerAddress) {
1354
+ try {
1355
+ const { portfolio } = await this.sdk.getPositions(ownerAddress);
1356
+ const raw = portfolio;
1357
+ return {
1358
+ predeployed: raw?.predeployed,
1359
+ hasActiveSessionKey: raw?.hasActiveSessionKey
1360
+ };
1361
+ } catch (error) {
1362
+ console.warn(
1363
+ "[zyfai] getPositions wallet-state read failed (non-fatal):",
1364
+ error instanceof Error ? error.message : String(error)
1365
+ );
1366
+ return {};
1367
+ }
1368
+ }
1339
1369
  async isPredeployedPoolWallet(ownerAddress, smartWallet) {
1370
+ const { predeployed } = await this.readWalletState(ownerAddress);
1371
+ if (typeof predeployed === "boolean") return predeployed;
1372
+ const internals = this.sdk;
1373
+ if (typeof internals.isPredeployed === "boolean") {
1374
+ return internals.isPredeployed;
1375
+ }
1340
1376
  try {
1341
1377
  const byEoa = await this.sdk.getSmartWalletByEOA(ownerAddress);
1342
1378
  return typeof byEoa?.smartWallet === "string" && byEoa.smartWallet.toLowerCase() === smartWallet.toLowerCase();
@@ -1378,7 +1414,13 @@ var ZyfaiAgent = class {
1378
1414
  chainId
1379
1415
  );
1380
1416
  if (!wallet.isDeployed) return;
1381
- await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
1417
+ const { hasActiveSessionKey } = await this.readWalletState(ownerAddress);
1418
+ await this.ensureSessionKey(
1419
+ ownerAddress,
1420
+ chainId,
1421
+ wallet.address,
1422
+ hasActiveSessionKey
1423
+ );
1382
1424
  } catch (error) {
1383
1425
  console.warn(
1384
1426
  "[zyfai] session-key check at activation failed (non-fatal):",
@@ -1386,15 +1428,19 @@ var ZyfaiAgent = class {
1386
1428
  );
1387
1429
  }
1388
1430
  }
1389
- async ensureSessionKey(ownerAddress, chainId, smartWallet) {
1431
+ async ensureSessionKey(ownerAddress, chainId, smartWallet, hasActiveSessionKey) {
1390
1432
  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
- });
1433
+ if (hasActiveSessionKey === false) {
1434
+ console.warn(
1435
+ `[zyfai] no session key on record for ${ownerAddress}; creating one for chain ${chainId}.`
1436
+ );
1437
+ await this.sdk.createSessionKey(ownerAddress, chainId);
1438
+ return;
1439
+ }
1440
+ const installed = await this.readSmartSessionsInstalled(
1441
+ chainId,
1442
+ smartWallet
1443
+ );
1398
1444
  if (installed) return;
1399
1445
  console.warn(
1400
1446
  `[zyfai] Safe ${smartWallet} has no smart-sessions validator on chain ${chainId}; creating a session key so the agent can allocate.`
@@ -1407,6 +1453,16 @@ var ZyfaiAgent = class {
1407
1453
  );
1408
1454
  }
1409
1455
  }
1456
+ /** Ground truth for "can Zyfai's automation act on this Safe, on this chain". */
1457
+ async readSmartSessionsInstalled(chainId, smartWallet) {
1458
+ return this.getPublicClient(chainId).readContract({
1459
+ address: smartWallet,
1460
+ abi: ERC7579_IS_MODULE_INSTALLED_ABI,
1461
+ functionName: "isModuleInstalled",
1462
+ // moduleTypeId 1 = validator (ERC-7579)
1463
+ args: [1n, import_sdk.SMART_SESSIONS_VALIDATOR, "0x"]
1464
+ });
1465
+ }
1410
1466
  /**
1411
1467
  * Guarantee the user's Safe has code on `chainId` before anything transfers
1412
1468
  * funds into it, and return its address.
@@ -1428,7 +1484,13 @@ var ZyfaiAgent = class {
1428
1484
  async ensureWalletDeployed(ownerAddress, chainId) {
1429
1485
  const wallet = await this.sdk.getSmartWalletAddress(ownerAddress, chainId);
1430
1486
  if (wallet.isDeployed) {
1431
- await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
1487
+ const { hasActiveSessionKey } = await this.readWalletState(ownerAddress);
1488
+ await this.ensureSessionKey(
1489
+ ownerAddress,
1490
+ chainId,
1491
+ wallet.address,
1492
+ hasActiveSessionKey
1493
+ );
1432
1494
  return wallet.address;
1433
1495
  }
1434
1496
  const poolFirst = await this.isPredeployedPoolWallet(
package/dist/index.js CHANGED
@@ -1303,7 +1303,43 @@ var ZyfaiAgent = class {
1303
1303
  * recoverable (ensureWalletDeployed tries the other deploy call), but
1304
1304
  * failing the deposit outright is not.
1305
1305
  */
1306
+ /**
1307
+ * Zyfai's own answer to "what kind of wallet is this, and can the agent act on
1308
+ * it", read from the positions payload (`GET /data/position`, which
1309
+ * `getPositions` wraps).
1310
+ *
1311
+ * `predeployed` and `hasActiveSessionKey` are both returned at runtime but
1312
+ * declared on neither `Portfolio` nor their docs, hence the cast. Verified
1313
+ * live: an old wallet reports `{predeployed: false, hasActiveSessionKey:
1314
+ * false}` while a pool wallet reports `{true, true}`.
1315
+ *
1316
+ * Preferred over the SDK's private `isPredeployed`, which is cached from the
1317
+ * login response and can go stale mid-session. Returns an empty object on any
1318
+ * failure so every caller degrades to its own fallback.
1319
+ */
1320
+ async readWalletState(ownerAddress) {
1321
+ try {
1322
+ const { portfolio } = await this.sdk.getPositions(ownerAddress);
1323
+ const raw = portfolio;
1324
+ return {
1325
+ predeployed: raw?.predeployed,
1326
+ hasActiveSessionKey: raw?.hasActiveSessionKey
1327
+ };
1328
+ } catch (error) {
1329
+ console.warn(
1330
+ "[zyfai] getPositions wallet-state read failed (non-fatal):",
1331
+ error instanceof Error ? error.message : String(error)
1332
+ );
1333
+ return {};
1334
+ }
1335
+ }
1306
1336
  async isPredeployedPoolWallet(ownerAddress, smartWallet) {
1337
+ const { predeployed } = await this.readWalletState(ownerAddress);
1338
+ if (typeof predeployed === "boolean") return predeployed;
1339
+ const internals = this.sdk;
1340
+ if (typeof internals.isPredeployed === "boolean") {
1341
+ return internals.isPredeployed;
1342
+ }
1307
1343
  try {
1308
1344
  const byEoa = await this.sdk.getSmartWalletByEOA(ownerAddress);
1309
1345
  return typeof byEoa?.smartWallet === "string" && byEoa.smartWallet.toLowerCase() === smartWallet.toLowerCase();
@@ -1345,7 +1381,13 @@ var ZyfaiAgent = class {
1345
1381
  chainId
1346
1382
  );
1347
1383
  if (!wallet.isDeployed) return;
1348
- await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
1384
+ const { hasActiveSessionKey } = await this.readWalletState(ownerAddress);
1385
+ await this.ensureSessionKey(
1386
+ ownerAddress,
1387
+ chainId,
1388
+ wallet.address,
1389
+ hasActiveSessionKey
1390
+ );
1349
1391
  } catch (error) {
1350
1392
  console.warn(
1351
1393
  "[zyfai] session-key check at activation failed (non-fatal):",
@@ -1353,15 +1395,19 @@ var ZyfaiAgent = class {
1353
1395
  );
1354
1396
  }
1355
1397
  }
1356
- async ensureSessionKey(ownerAddress, chainId, smartWallet) {
1398
+ async ensureSessionKey(ownerAddress, chainId, smartWallet, hasActiveSessionKey) {
1357
1399
  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
- });
1400
+ if (hasActiveSessionKey === false) {
1401
+ console.warn(
1402
+ `[zyfai] no session key on record for ${ownerAddress}; creating one for chain ${chainId}.`
1403
+ );
1404
+ await this.sdk.createSessionKey(ownerAddress, chainId);
1405
+ return;
1406
+ }
1407
+ const installed = await this.readSmartSessionsInstalled(
1408
+ chainId,
1409
+ smartWallet
1410
+ );
1365
1411
  if (installed) return;
1366
1412
  console.warn(
1367
1413
  `[zyfai] Safe ${smartWallet} has no smart-sessions validator on chain ${chainId}; creating a session key so the agent can allocate.`
@@ -1374,6 +1420,16 @@ var ZyfaiAgent = class {
1374
1420
  );
1375
1421
  }
1376
1422
  }
1423
+ /** Ground truth for "can Zyfai's automation act on this Safe, on this chain". */
1424
+ async readSmartSessionsInstalled(chainId, smartWallet) {
1425
+ return this.getPublicClient(chainId).readContract({
1426
+ address: smartWallet,
1427
+ abi: ERC7579_IS_MODULE_INSTALLED_ABI,
1428
+ functionName: "isModuleInstalled",
1429
+ // moduleTypeId 1 = validator (ERC-7579)
1430
+ args: [1n, SMART_SESSIONS_VALIDATOR, "0x"]
1431
+ });
1432
+ }
1377
1433
  /**
1378
1434
  * Guarantee the user's Safe has code on `chainId` before anything transfers
1379
1435
  * funds into it, and return its address.
@@ -1395,7 +1451,13 @@ var ZyfaiAgent = class {
1395
1451
  async ensureWalletDeployed(ownerAddress, chainId) {
1396
1452
  const wallet = await this.sdk.getSmartWalletAddress(ownerAddress, chainId);
1397
1453
  if (wallet.isDeployed) {
1398
- await this.ensureSessionKey(ownerAddress, chainId, wallet.address);
1454
+ const { hasActiveSessionKey } = await this.readWalletState(ownerAddress);
1455
+ await this.ensureSessionKey(
1456
+ ownerAddress,
1457
+ chainId,
1458
+ wallet.address,
1459
+ hasActiveSessionKey
1460
+ );
1399
1461
  return wallet.address;
1400
1462
  }
1401
1463
  const poolFirst = await this.isPredeployedPoolWallet(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.6",
3
+ "version": "0.7.7-beta.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",