@owney/sdk 0.2.7 → 0.2.9

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
@@ -303,17 +303,13 @@ function mapApyByStrategy(raw) {
303
303
  }
304
304
 
305
305
  // src/agents/zyfai/zyfai.agent.ts
306
- var ZYFAI_TIMING_PREFIX = "[AgentTiming][zyfai]";
307
- function logTiming(label, startedAt, meta) {
308
- const elapsedMs = Date.now() - startedAt;
309
- if (meta) {
310
- console.log(`${ZYFAI_TIMING_PREFIX} ${label} ${elapsedMs}ms`, meta);
311
- return;
312
- }
313
- console.log(`${ZYFAI_TIMING_PREFIX} ${label} ${elapsedMs}ms`);
314
- }
306
+ var DEFAULT_ZYFAI_RPC_URLS = {
307
+ 8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
308
+ 42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V"
309
+ };
315
310
  var ZyfaiAgent = class {
316
311
  id = "zyfai";
312
+ minDepositAmount = "0";
317
313
  supportedChainIds = [8453, 42161];
318
314
  supportedAssets = [
319
315
  {
@@ -332,8 +328,11 @@ var ZyfaiAgent = class {
332
328
  connectedChainId = null;
333
329
  smartWalletCache = /* @__PURE__ */ new Map();
334
330
  connectAuthPromise = null;
335
- constructor(apiKey) {
336
- this.sdk = new import_sdk.ZyfaiSDK({ apiKey });
331
+ constructor(apiKey, rpcUrls) {
332
+ this.sdk = new import_sdk.ZyfaiSDK({
333
+ apiKey,
334
+ rpcUrls: rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS
335
+ });
337
336
  }
338
337
  // --- Private helpers ---
339
338
  getAddress() {
@@ -347,17 +346,12 @@ var ZyfaiAgent = class {
347
346
  }
348
347
  /** Light connect: SIWE auth only. Re-auths if chain changed. */
349
348
  async connectAuth(state, chainId) {
350
- const startedAt = Date.now();
351
349
  const validChainId = isValidChainId(chainId);
352
350
  if (this.connectedAddress && this.connectedChainId === validChainId) {
353
- logTiming("connectAuth cache-hit", startedAt, { chainId: validChainId });
354
351
  return;
355
352
  }
356
353
  if (this.connectAuthPromise) {
357
354
  await this.connectAuthPromise;
358
- logTiming("connectAuth awaited-inflight", startedAt, {
359
- chainId: validChainId
360
- });
361
355
  return;
362
356
  }
363
357
  this.connectAuthPromise = (async () => {
@@ -370,69 +364,40 @@ var ZyfaiAgent = class {
370
364
  })();
371
365
  try {
372
366
  await this.connectAuthPromise;
373
- logTiming("connectAuth success", startedAt, { chainId: validChainId });
374
367
  } finally {
375
368
  this.connectAuthPromise = null;
376
369
  }
377
370
  }
378
371
  /** Full connect: SIWE auth + Safe deploy check + session key. */
379
372
  async connectFull(state, chainId) {
380
- const startedAt = Date.now();
381
373
  await this.connectAuth(state, chainId);
382
374
  const validChainId = isValidChainId(chainId);
383
375
  const address = this.getAddress();
384
- const walletLookupStart = Date.now();
385
376
  const wallet = await this.sdk.getSmartWalletAddress(address, validChainId);
386
- logTiming("connectFull getSmartWalletAddress", walletLookupStart, {
387
- chainId: validChainId
388
- });
389
377
  this.smartWalletCache.set(`${address}_${validChainId}`, wallet.address);
390
378
  if (!wallet.isDeployed) {
391
- const deployStart = Date.now();
392
379
  await this.sdk.deploySafe(address, validChainId, "aggressive", true);
393
- logTiming("connectFull deploySafe", deployStart, {
394
- chainId: validChainId
395
- });
396
380
  }
397
- const userDetailsStart = Date.now();
398
381
  const user = await this.sdk.getUserDetails();
399
- logTiming("connectFull getUserDetails", userDetailsStart, {
400
- chainId: validChainId
401
- });
402
382
  if (!user.hasActiveSessionKey) {
403
- const sessionKeyStart = Date.now();
404
383
  await this.sdk.createSessionKey(address, validChainId);
405
- logTiming("connectFull createSessionKey", sessionKeyStart, {
406
- chainId: validChainId
407
- });
408
384
  }
409
- logTiming("connectFull success", startedAt, { chainId: validChainId });
410
385
  }
411
386
  /** Connect + resolve smart wallet address for read operations. */
412
387
  async resolveSmartWallet(state, chainId) {
413
- const startedAt = Date.now();
414
388
  await this.connectAuth(state, chainId);
415
389
  const validChainId = isValidChainId(chainId);
416
390
  const ownerAddress = this.getAddress();
417
391
  const cacheKey = `${ownerAddress}_${validChainId}`;
418
392
  let smartWallet = this.smartWalletCache.get(cacheKey);
419
393
  if (!smartWallet) {
420
- const lookupStart = Date.now();
421
394
  const { address } = await this.sdk.getSmartWalletAddress(
422
395
  ownerAddress,
423
396
  validChainId
424
397
  );
425
- logTiming("resolveSmartWallet remote-lookup", lookupStart, {
426
- chainId: validChainId
427
- });
428
398
  smartWallet = address;
429
399
  this.smartWalletCache.set(cacheKey, smartWallet);
430
- } else {
431
- logTiming("resolveSmartWallet cache-hit", startedAt, {
432
- chainId: validChainId
433
- });
434
400
  }
435
- logTiming("resolveSmartWallet ready", startedAt, { chainId: validChainId });
436
401
  return { smartWallet, chainId: validChainId };
437
402
  }
438
403
  // --- IAgent: Connection lifecycle ---
@@ -492,14 +457,8 @@ var ZyfaiAgent = class {
492
457
  }
493
458
  // --- IAgent: Portfolio reads ---
494
459
  async getBalances(state, chainId) {
495
- const startedAt = Date.now();
496
460
  const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
497
- const portfolioStart = Date.now();
498
461
  const raw = await this.sdk.getPortfolio(this.getAddress());
499
- logTiming("getBalances getPortfolio", portfolioStart, {
500
- chainId: validChainId
501
- });
502
- logTiming("getBalances success", startedAt, { chainId: validChainId });
503
462
  return mapBalances(raw, validChainId, smartWallet);
504
463
  }
505
464
  async getEarnings(state, chainId) {
@@ -564,13 +523,13 @@ function mapWithdraw2(raw) {
564
523
  function mapPortfolioBalances(raw, smartWallet) {
565
524
  let total = 0;
566
525
  const tokens = [];
567
- for (const item of raw.result) {
568
- total += item.usd_value;
526
+ for (const item of raw.tokens) {
527
+ total += item.balanceFormatted;
569
528
  tokens.push({
570
- chain: item.chain.toUpperCase(),
571
- chainId: item.chain_id,
572
- asset: item.token === "USD\u20AE0" ? "USDT" : item.token,
573
- amount: String(item.usd_value)
529
+ chain: SUPPORTED_CHAINS[item.chain],
530
+ chainId: item.chain,
531
+ asset: item.symbol === "USD\u20AE0" ? "USDT" : item.symbol,
532
+ amount: item.balance
574
533
  });
575
534
  }
576
535
  return {
@@ -689,7 +648,7 @@ function mapHistory2(raw) {
689
648
  rewards: "Earned"
690
649
  };
691
650
  const filtered = raw.result.items.filter(
692
- (i) => i.status === "success" && i.transactions.length
651
+ (i) => !(i.type === "execution" && (i.status === "failed" || !i.transactions.length))
693
652
  );
694
653
  return {
695
654
  total: filtered.length,
@@ -753,18 +712,10 @@ function remapApyPerAssetToSymbols(raw) {
753
712
  var SAIL_API_BASE = "https://app.sail.money";
754
713
  var PROJECT_ID = "sail";
755
714
  var PAGE_ID = "home";
756
- var SAIL_TIMING_PREFIX = "[AgentTiming][sail]";
757
715
  var SAIL_PORTFOLIO_TIMEOUT_MS = 8e3;
758
- function logTiming2(label, startedAt, meta) {
759
- const elapsedMs = Date.now() - startedAt;
760
- if (meta) {
761
- console.log(`${SAIL_TIMING_PREFIX} ${label} ${elapsedMs}ms`, meta);
762
- return;
763
- }
764
- console.log(`${SAIL_TIMING_PREFIX} ${label} ${elapsedMs}ms`);
765
- }
766
716
  var SailAgent = class {
767
717
  id = "sail";
718
+ minDepositAmount = "4800000000";
768
719
  supportedChainIds = [8453, 42161];
769
720
  supportedAssets = [
770
721
  {
@@ -835,7 +786,6 @@ var SailAgent = class {
835
786
  }
836
787
  /** Initiate SIWE and sign with the user's wallet. */
837
788
  async signSiwe(state, chainId) {
838
- const startedAt = Date.now();
839
789
  const initiate = await this.request(
840
790
  "POST",
841
791
  `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/auth/initiate`,
@@ -850,7 +800,6 @@ var SailAgent = class {
850
800
  method: "personal_sign",
851
801
  params: [initiate.message, state.walletAddress]
852
802
  });
853
- logTiming2("signSiwe success", startedAt, { chainId });
854
803
  return {
855
804
  sessionId: initiate.sessionId,
856
805
  message: initiate.message,
@@ -859,14 +808,11 @@ var SailAgent = class {
859
808
  }
860
809
  /** Full connect: auth handles smart account creation via SIWE flow. */
861
810
  async connectFull(state, chainId) {
862
- const startedAt = Date.now();
863
811
  if (this.connectedAddress && this.connectedChainId === chainId) {
864
- logTiming2("connectFull cache-hit", startedAt, { chainId });
865
812
  return;
866
813
  }
867
814
  if (this.connectPromise) {
868
815
  await this.connectPromise;
869
- logTiming2("connectFull awaited-inflight", startedAt, { chainId });
870
816
  return;
871
817
  }
872
818
  if (!state.walletAddress) {
@@ -899,13 +845,11 @@ var SailAgent = class {
899
845
  })();
900
846
  try {
901
847
  await this.connectPromise;
902
- logTiming2("connectFull success", startedAt, { chainId });
903
848
  } finally {
904
849
  this.connectPromise = null;
905
850
  }
906
851
  }
907
852
  async resolveSmartWallet(state, chainId) {
908
- const startedAt = Date.now();
909
853
  await this.connectFull(state, chainId);
910
854
  const validChainId = isValidChainId(chainId);
911
855
  if (!this.smartWalletAddress) {
@@ -914,7 +858,6 @@ var SailAgent = class {
914
858
  "Wallet not connected. Call sdk.connect() first."
915
859
  );
916
860
  }
917
- logTiming2("resolveSmartWallet ready", startedAt, { chainId: validChainId });
918
861
  return {
919
862
  smartWallet: this.smartWalletAddress,
920
863
  chainId: validChainId
@@ -1039,13 +982,9 @@ var SailAgent = class {
1039
982
  }
1040
983
  // --- IAgent: Portfolio reads ---
1041
984
  async getBalances(state, chainId) {
1042
- const startedAt = Date.now();
1043
985
  const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1044
- const portfolioStart = Date.now();
1045
986
  try {
1046
- const raw = await this.getMetricsPortfolio(state, chainId);
1047
- logTiming2("getBalances getMetricsPortfolio", portfolioStart, { chainId });
1048
- logTiming2("getBalances success", startedAt, { chainId });
987
+ const raw = await this.getPortfolio();
1049
988
  return mapPortfolioBalances(raw, smartWallet);
1050
989
  } catch (error) {
1051
990
  if (error instanceof OwneyError && error.code === "API_SAIL_TIMEOUT") {
@@ -1055,9 +994,8 @@ var SailAgent = class {
1055
994
  chainId
1056
995
  }
1057
996
  );
1058
- logTiming2("getBalances timeout-fallback", startedAt, { chainId });
1059
997
  return mapPortfolioBalances(
1060
- { message: "timeout", result: [] },
998
+ { message: "timeout", tokens: [] },
1061
999
  smartWallet
1062
1000
  );
1063
1001
  }
@@ -1088,6 +1026,14 @@ var SailAgent = class {
1088
1026
  SAIL_PORTFOLIO_TIMEOUT_MS
1089
1027
  );
1090
1028
  }
1029
+ async getPortfolio() {
1030
+ return this.request(
1031
+ "GET",
1032
+ `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/portfolio/tokens`,
1033
+ void 0,
1034
+ SAIL_PORTFOLIO_TIMEOUT_MS
1035
+ );
1036
+ }
1091
1037
  async getMetricsEarnings(state, chainId) {
1092
1038
  const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1093
1039
  return this.request(
@@ -1095,7 +1041,7 @@ var SailAgent = class {
1095
1041
  `/api/v1/projects/${PROJECT_ID}/pages/${PAGE_ID}/metrics/earnings?smart_account=${smartWallet}`
1096
1042
  );
1097
1043
  }
1098
- async getMetricsBalance(state, chainId, currency) {
1044
+ async getMetricsBalance(state, chainId, currency = "usd") {
1099
1045
  const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1100
1046
  return this.request(
1101
1047
  "GET",
@@ -1243,27 +1189,16 @@ async function fetchAgentKeys(apiKey) {
1243
1189
  }
1244
1190
 
1245
1191
  // src/client.ts
1246
- var AGENT_CONSTRUCTORS = {
1247
- zyfai: ZyfaiAgent,
1248
- sail: SailAgent
1249
- };
1250
- var SDK_TIMING_PREFIX = "[OwneySDKTiming]";
1251
- function logTiming3(label, startedAt, meta) {
1252
- const elapsedMs = Date.now() - startedAt;
1253
- if (meta) {
1254
- console.log(`${SDK_TIMING_PREFIX} ${label} ${elapsedMs}ms`, meta);
1255
- return;
1256
- }
1257
- console.log(`${SDK_TIMING_PREFIX} ${label} ${elapsedMs}ms`);
1258
- }
1259
1192
  var OwneySDK = class {
1260
1193
  agents = /* @__PURE__ */ new Map();
1261
1194
  activeAgents = /* @__PURE__ */ new Set();
1262
1195
  state = null;
1263
1196
  apiKey;
1197
+ zyfaiRpcUrls;
1264
1198
  initializingAgentsPromise = null;
1265
1199
  constructor(config) {
1266
1200
  this.apiKey = config.apiKey;
1201
+ this.zyfaiRpcUrls = config.zyfaiRpcUrls;
1267
1202
  }
1268
1203
  /**
1269
1204
  * Establish connection state for all subsequent SDK calls.
@@ -1347,10 +1282,9 @@ var OwneySDK = class {
1347
1282
  this.initializingAgentsPromise = (async () => {
1348
1283
  const agentKeys = await fetchAgentKeys(this.apiKey);
1349
1284
  for (const { key, agent_type } of agentKeys) {
1350
- const AgentClass = AGENT_CONSTRUCTORS[agent_type];
1351
- if (!AgentClass)
1285
+ const agent = this.createAgent(agent_type, key);
1286
+ if (!agent)
1352
1287
  continue;
1353
- const agent = new AgentClass(key);
1354
1288
  this.agents.set(agent_type, agent);
1355
1289
  }
1356
1290
  if (this.agents.size === 0) {
@@ -1367,6 +1301,15 @@ var OwneySDK = class {
1367
1301
  this.initializingAgentsPromise = null;
1368
1302
  }
1369
1303
  }
1304
+ createAgent(agentId, key) {
1305
+ if (agentId === "zyfai") {
1306
+ return new ZyfaiAgent(key, this.zyfaiRpcUrls);
1307
+ }
1308
+ if (agentId === "sail") {
1309
+ return new SailAgent(key);
1310
+ }
1311
+ return null;
1312
+ }
1370
1313
  // --- Account lifecycle ---
1371
1314
  /**
1372
1315
  * Activate the user's smart wallet for the specified agents, or all chain-compatible agents if omitted.
@@ -1379,7 +1322,6 @@ var OwneySDK = class {
1379
1322
  * throws before activating any agent.
1380
1323
  */
1381
1324
  async activateAgent(chainId, agentId) {
1382
- const startedAt = Date.now();
1383
1325
  const state = this.requireState();
1384
1326
  await this.ensureAgentsInitialized();
1385
1327
  if (agentId !== void 0) {
@@ -1407,20 +1349,11 @@ var OwneySDK = class {
1407
1349
  state.chainId = chainId;
1408
1350
  Promise.all(
1409
1351
  agents.map(async (agent) => {
1410
- const agentStart = Date.now();
1411
1352
  await agent.activateAgent(state, chainId);
1412
- logTiming3("activateAgent background-agent-ready", agentStart, {
1413
- chainId,
1414
- agentId: agent.id
1415
- });
1416
1353
  })
1417
1354
  ).catch((error) => {
1418
1355
  console.error("activateAgent background init failed:", error);
1419
1356
  });
1420
- logTiming3("activateAgent scheduled", startedAt, {
1421
- chainId,
1422
- agentIds: uniqueIds
1423
- });
1424
1357
  return;
1425
1358
  }
1426
1359
  const compatible = [...this.agents.values()].filter(
@@ -1440,24 +1373,15 @@ var OwneySDK = class {
1440
1373
  state.chainId = chainId;
1441
1374
  Promise.all(
1442
1375
  compatible.map(async (agent) => {
1443
- const agentStart = Date.now();
1444
1376
  await agent.activateAgent(state, chainId);
1445
- logTiming3("activateAgent background-agent-ready", agentStart, {
1446
- chainId,
1447
- agentId: agent.id
1448
- });
1449
1377
  })
1450
1378
  ).catch((error) => {
1451
1379
  console.error("activateAgent background init failed:", error);
1452
1380
  });
1453
- logTiming3("activateAgent scheduled", startedAt, {
1454
- chainId,
1455
- agentIds: compatible.map((agent) => agent.id)
1456
- });
1457
1381
  }
1458
1382
  /**
1459
1383
  * Deposit funds into a specific agent, or split equally across all agents if agentId is omitted.
1460
- * Validates that the asset is supported by the target agent(s) on the active chain.
1384
+ * Validates that the asset is supported and amount meets minimums for the target agent(s).
1461
1385
  * @param options - Deposit parameters
1462
1386
  * @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
1463
1387
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
@@ -1469,28 +1393,29 @@ var OwneySDK = class {
1469
1393
  */
1470
1394
  async deposit(options) {
1471
1395
  const { amount, asset, depositCallback, agentId } = options;
1396
+ if (BigInt(amount) === 0n) {
1397
+ return { agentResults: {} };
1398
+ }
1472
1399
  const state = this.requireState();
1473
1400
  const chainId = this.requireChainId();
1474
1401
  if (agentId) {
1475
1402
  const agent = this.getAgent(agentId);
1476
1403
  this.validateAssetSupport(agent, chainId, asset);
1404
+ this.validateMinDepositAmount(agent, amount);
1477
1405
  return agent.deposit(state, chainId, amount, depositCallback);
1478
1406
  }
1479
- const eligibleAgents = this.getEligibleAgents(chainId, asset);
1480
1407
  const totalAmount = BigInt(amount);
1481
- if (totalAmount < BigInt(eligibleAgents.length)) {
1408
+ const eligibleAgents = this.getEligibleAgents(chainId, asset);
1409
+ const agentAmounts = this.splitDepositAmount(totalAmount, eligibleAgents);
1410
+ if (agentAmounts.length === 0) {
1482
1411
  throw new OwneyError(
1483
- "DEPOSIT_AMOUNT_TOO_SMALL",
1484
- `Amount "${amount}" is too small to split across ${eligibleAgents.length} agents.`,
1485
- { amount, agentCount: eligibleAgents.length }
1412
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1413
+ `Amount "${amount}" cannot satisfy minimum deposit requirements for any eligible agent.`,
1414
+ { amount }
1486
1415
  );
1487
1416
  }
1488
- const perAgent = totalAmount / BigInt(eligibleAgents.length);
1489
- const remainder = totalAmount % BigInt(eligibleAgents.length);
1490
1417
  const agentResults = {};
1491
- for (let i = 0; i < eligibleAgents.length; i++) {
1492
- const agent = eligibleAgents[i];
1493
- const agentAmount = i === eligibleAgents.length - 1 ? String(perAgent + remainder) : String(perAgent);
1418
+ for (const { agent, amount: agentAmount } of agentAmounts) {
1494
1419
  agentResults[agent.id] = await agent.deposit(
1495
1420
  state,
1496
1421
  chainId,
@@ -1500,6 +1425,37 @@ var OwneySDK = class {
1500
1425
  }
1501
1426
  return { agentResults };
1502
1427
  }
1428
+ splitDepositAmount(totalAmount, agents) {
1429
+ if (agents.length === 0)
1430
+ return [];
1431
+ const perAgent = totalAmount / BigInt(agents.length);
1432
+ const remainder = totalAmount % BigInt(agents.length);
1433
+ const splits = agents.map((agent, i) => ({
1434
+ agent,
1435
+ amount: i === agents.length - 1 ? perAgent + remainder : perAgent
1436
+ }));
1437
+ const valid = splits.filter(
1438
+ (s) => s.amount >= BigInt(s.agent.minDepositAmount)
1439
+ );
1440
+ if (valid.length === agents.length) {
1441
+ return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
1442
+ }
1443
+ return this.splitDepositAmount(totalAmount, valid.map((s) => s.agent));
1444
+ }
1445
+ validateMinDepositAmount(agent, amount) {
1446
+ const minDepositAmount = BigInt(agent.minDepositAmount);
1447
+ const parsedAmount = BigInt(amount);
1448
+ if (parsedAmount < minDepositAmount) {
1449
+ throw new OwneyError(
1450
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1451
+ `Amount "${amount}" is below the required minimum deposit for agent "${agent.id}".`,
1452
+ {
1453
+ agentId: agent.id,
1454
+ amount
1455
+ }
1456
+ );
1457
+ }
1458
+ }
1503
1459
  validateAssetSupport(agent, chainId, asset) {
1504
1460
  const chainAssets = agent.supportedAssets.find(
1505
1461
  (sa) => sa.chainId === chainId
@@ -1578,12 +1534,10 @@ var OwneySDK = class {
1578
1534
  * @returns {AgentBalance} for a single agent, or {OwneyBalances} with totalBalance and per-agent breakdown
1579
1535
  */
1580
1536
  async getBalances(agentId) {
1581
- const startedAt = Date.now();
1582
1537
  const state = this.requireState();
1583
1538
  const chainId = this.requireChainId();
1584
1539
  if (agentId) {
1585
1540
  const result = await this.getAgent(agentId).getBalances(state, chainId);
1586
- logTiming3("getBalances single-agent", startedAt, { chainId, agentId });
1587
1541
  return result;
1588
1542
  }
1589
1543
  let totalBalance = 0;
@@ -1591,12 +1545,7 @@ var OwneySDK = class {
1591
1545
  const entries = [...this.getActiveAgents().entries()];
1592
1546
  const balanceResults = await Promise.allSettled(
1593
1547
  entries.map(async ([id, agent]) => {
1594
- const agentStartedAt = Date.now();
1595
1548
  const b = await agent.getBalances(state, chainId);
1596
- logTiming3("getBalances per-agent", agentStartedAt, {
1597
- chainId,
1598
- agentId: id
1599
- });
1600
1549
  return [id, b];
1601
1550
  })
1602
1551
  );
@@ -1617,11 +1566,6 @@ var OwneySDK = class {
1617
1566
  "Failed to fetch balances for all active agents."
1618
1567
  );
1619
1568
  }
1620
- logTiming3("getBalances aggregate", startedAt, {
1621
- chainId,
1622
- totalAgents: entries.length,
1623
- successCount
1624
- });
1625
1569
  return {
1626
1570
  totalBalance: String(totalBalance),
1627
1571
  agentBalances: results
@@ -1694,18 +1638,30 @@ var OwneySDK = class {
1694
1638
  results[id] = apy;
1695
1639
  }
1696
1640
  const balances = {};
1697
- let totalBalance = 0;
1698
1641
  for (const [id, bal] of balanceResults) {
1699
1642
  balances[id] = bal;
1700
- totalBalance += bal;
1701
1643
  }
1702
1644
  let totalApy = 0;
1703
- if (totalBalance > 0) {
1645
+ let relevantBalance = 0;
1646
+ for (const id of Object.keys(results)) {
1647
+ const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
1648
+ if (agentApy === 0)
1649
+ continue;
1650
+ relevantBalance += balances[id];
1651
+ }
1652
+ if (relevantBalance > 0) {
1704
1653
  for (const id of Object.keys(results)) {
1705
- const weight = balances[id] / totalBalance;
1706
- totalApy += Number(results[id].weightedApyAfterFee ?? 0) * weight;
1654
+ const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
1655
+ if (agentApy === 0)
1656
+ continue;
1657
+ const weight = balances[id] / relevantBalance;
1658
+ totalApy += agentApy * weight;
1707
1659
  }
1708
1660
  }
1661
+ console.log("account apy", {
1662
+ totalApy: String(totalApy),
1663
+ agentApy: results
1664
+ });
1709
1665
  return {
1710
1666
  totalApy: String(totalApy),
1711
1667
  agentApy: results
package/dist/index.d.cts CHANGED
@@ -1,5 +1,11 @@
1
+ type ZyfaiRpcUrlsConfig = Partial<Record<(typeof SUPPORTED_CHAIN_IDS)[number], string>>;
1
2
  interface OwneySDKConfig {
2
3
  apiKey: string;
4
+ /**
5
+ * Optional per-chain RPC overrides for Zyfai SDK network calls.
6
+ * Example: { 8453: "https://...", 42161: "https://..." }
7
+ */
8
+ zyfaiRpcUrls?: ZyfaiRpcUrlsConfig;
3
9
  }
4
10
  interface ConnectionState {
5
11
  provider: any;
@@ -18,6 +24,7 @@ interface IAgent {
18
24
  readonly id: string;
19
25
  readonly supportedChainIds: readonly OwneySupportedChainId[];
20
26
  readonly supportedAssets: readonly AgentSupportedAssets[];
27
+ readonly minDepositAmount: string;
21
28
  disconnect(): Promise<void>;
22
29
  activateAgent(state: ConnectionState, chainId: number): Promise<void>;
23
30
  deposit(state: ConnectionState, chainId: number, amount: string, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
@@ -190,10 +197,6 @@ interface AgentApy {
190
197
  interface OwneyAgentApy {
191
198
  agentApy: Record<AgentId, AgentApy>;
192
199
  }
193
- interface OwneyRouteResponse {
194
- agent: AgentId;
195
- chainId: number;
196
- }
197
200
  interface OwneyAgentAllocation {
198
201
  agentAllocation: Record<AgentId, number>;
199
202
  }
@@ -203,6 +206,7 @@ declare class OwneySDK {
203
206
  private activeAgents;
204
207
  private state;
205
208
  private apiKey;
209
+ private zyfaiRpcUrls?;
206
210
  private initializingAgentsPromise;
207
211
  constructor(config: OwneySDKConfig);
208
212
  /**
@@ -231,6 +235,7 @@ declare class OwneySDK {
231
235
  private getAgent;
232
236
  private getActiveAgents;
233
237
  private ensureAgentsInitialized;
238
+ private createAgent;
234
239
  /**
235
240
  * Activate the user's smart wallet for the specified agents, or all chain-compatible agents if omitted.
236
241
  * Deploys the Safe contract and creates a session key if not already set up.
@@ -244,7 +249,7 @@ declare class OwneySDK {
244
249
  activateAgent(chainId: number, agentId?: AgentId[]): Promise<void>;
245
250
  /**
246
251
  * Deposit funds into a specific agent, or split equally across all agents if agentId is omitted.
247
- * Validates that the asset is supported by the target agent(s) on the active chain.
252
+ * Validates that the asset is supported and amount meets minimums for the target agent(s).
248
253
  * @param options - Deposit parameters
249
254
  * @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
250
255
  * @param options.asset - Asset symbol to deposit (e.g. "USDC")
@@ -255,6 +260,8 @@ declare class OwneySDK {
255
260
  * @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
256
261
  */
257
262
  deposit(options: DepositOptions): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
263
+ private splitDepositAmount;
264
+ private validateMinDepositAmount;
258
265
  private validateAssetSupport;
259
266
  private getEligibleAgents;
260
267
  /**
@@ -334,7 +341,7 @@ declare class OwneySDK {
334
341
  getAgentAllocation(): Promise<OwneyAgentAllocation>;
335
342
  }
336
343
 
337
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_TOO_SMALL" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
344
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
338
345
  declare class OwneyError extends Error {
339
346
  readonly code: OwneyErrorCode;
340
347
  readonly details?: Record<string, unknown>;
@@ -358,4 +365,4 @@ declare class AgentChainIncompatibleError extends OwneyError {
358
365
  }>, connectedChainId: number);
359
366
  }
360
367
 
361
- export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneyRouteResponse, OwneySDK, OwneySDKConfig, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };
368
+ export { AccountAgentApy, AccountApyOptions, AgentApy, AgentApyDetails, AgentBalance, AgentChainIncompatibleError, AgentEarnings, AgentHistoryEntry, AgentId, AgentNotFoundError, AgentSupportedAssets, AgentUserProfile, AgentWithdrawResult, AgentsApyOptions, Asset, ConnectionState, DailyApyDays, DepositCallback, DepositOptions, HistoryAction, HistoryFilters, HistoryOptions, HistoryTransaction, IAgent, NotConnectedError, OwneyAccountApy, OwneyAgentAllocation, OwneyAgentApy, OwneyAgentHistory, OwneyAgentStatus, OwneyBalances, OwneyDepositResult, OwneyEarnings, OwneyError, OwneyErrorCode, OwneyMultiDepositResult, OwneySDK, OwneySDKConfig, OwneySupportedChainId, OwneySupportedChains, OwneySupportedTokens, OwneyToken, OwneyUserProfile, OwneyWithdrawResult, RebalanceLog, WithdrawOptions };