@owney/sdk 0.7.7 → 0.7.8

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 CHANGED
@@ -263,6 +263,25 @@ console.log(allEarnings.agentEarnings.zyfai.lifetimeEarnings); // 42.5
263
263
  console.log(allEarnings.agentEarnings.zyfai.tokens); // per-chain, per-asset breakdown
264
264
  ```
265
265
 
266
+ ### `refreshEarnings(agentId?)`
267
+
268
+ Refresh earnings for agents whose earnings data may be outdated. If the latest
269
+ snapshot is less than one hour old, the SDK returns it without recalculating.
270
+
271
+ | Param | Type | Description |
272
+ | --------- | -------------------- | ------------------------------------ |
273
+ | `agentId` | `"zyfai"` (optional) | Agent to refresh. Omit for all agents. |
274
+
275
+ Returns: `AgentEarnings` (single agent) or `OwneyEarnings` (all agents)
276
+
277
+ ```typescript
278
+ // Single agent
279
+ const refreshed = await sdk.refreshEarnings("zyfai");
280
+
281
+ // All agents
282
+ const allRefreshed = await sdk.refreshEarnings();
283
+ ```
284
+
266
285
  ### `getAccountApy({ agentId?, days })`
267
286
 
268
287
  Get the weighted APY for the user's account. When querying all agents, the total APY is a balance-weighted average.
package/dist/index.cjs CHANGED
@@ -871,6 +871,7 @@ var WETH_ADDRESS_BY_CHAIN = {
871
871
  var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: import_chains.mainnet };
872
872
  var SPLITTING_ASSETS = ["USDC", "WETH"];
873
873
  var POOL_POLICY_CHAIN_IDS = [8453, 42161, 1];
874
+ var EARNINGS_REFRESH_COOLDOWN_MS = 60 * 60 * 1e3;
874
875
  var ZyfaiAgent = class {
875
876
  id = "zyfai";
876
877
  supportedChainIds = [8453, 42161, 1];
@@ -922,6 +923,7 @@ var ZyfaiAgent = class {
922
923
  // successful decode is cached forever; failures are NOT cached so a transient
923
924
  // RPC error retries on the next fetch.
924
925
  withdrawAmountCache = /* @__PURE__ */ new Map();
926
+ earningsRefreshInFlight = null;
925
927
  constructor(apiKey, rpcUrls, referralSource) {
926
928
  this.rpcUrls = rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS;
927
929
  this.sdk = new import_sdk.ZyfaiSDK({
@@ -1719,6 +1721,22 @@ var ZyfaiAgent = class {
1719
1721
  const raw = await this.sdk.getOnchainEarnings(smartWallet);
1720
1722
  return mapEarnings(raw, smartWallet);
1721
1723
  }
1724
+ async refreshEarnings(state, chainId) {
1725
+ if (this.earningsRefreshInFlight) return this.earningsRefreshInFlight;
1726
+ this.earningsRefreshInFlight = (async () => {
1727
+ const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1728
+ const current = await this.sdk.getOnchainEarnings(smartWallet);
1729
+ const lastCheck = current.data.lastCheckTimestamp ? Date.parse(current.data.lastCheckTimestamp) : Number.NaN;
1730
+ const isFresh = Number.isFinite(lastCheck) && Date.now() - lastCheck < EARNINGS_REFRESH_COOLDOWN_MS;
1731
+ const earnings = isFresh ? current : await this.sdk.calculateOnchainEarnings(smartWallet);
1732
+ return mapEarnings(earnings, smartWallet);
1733
+ })();
1734
+ try {
1735
+ return await this.earningsRefreshInFlight;
1736
+ } finally {
1737
+ this.earningsRefreshInFlight = null;
1738
+ }
1739
+ }
1722
1740
  async getAccountApy(state, chainId, days, tokenSymbol) {
1723
1741
  const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1724
1742
  const raw = await this.sdk.getDailyApyHistory(smartWallet, days);
@@ -3419,6 +3437,28 @@ var OwneySDK = class {
3419
3437
  agentEarnings: results
3420
3438
  };
3421
3439
  }
3440
+ /**
3441
+ * Return refreshed earnings while letting each agent own its refresh policy.
3442
+ * Agents without a refresh capability fall back to their current snapshot.
3443
+ */
3444
+ async refreshEarnings(agentId) {
3445
+ const state = this.requireState();
3446
+ const chainId = this.requireChainId();
3447
+ const refreshAgent = (agent) => agent.refreshEarnings?.(state, chainId) ?? agent.getEarnings(state, chainId);
3448
+ if (agentId) return refreshAgent(this.getAgent(agentId));
3449
+ let totalEarnings = 0;
3450
+ const agentEarnings = {};
3451
+ const refreshed = await Promise.all(
3452
+ [...this.getActiveAgents().entries()].map(
3453
+ async ([id, agent]) => [id, await refreshAgent(agent)]
3454
+ )
3455
+ );
3456
+ for (const [id, earnings] of refreshed) {
3457
+ agentEarnings[id] = earnings;
3458
+ totalEarnings += Number(earnings.lifetimeEarnings);
3459
+ }
3460
+ return { totalEarnings: String(totalEarnings), agentEarnings };
3461
+ }
3422
3462
  /**
3423
3463
  * Get the weighted APY for the user's account over a time period.
3424
3464
  * When querying all agents, the total APY is a balance-weighted average.
package/dist/index.d.cts CHANGED
@@ -383,6 +383,11 @@ interface IAgent {
383
383
  withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
384
384
  getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
385
385
  getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
386
+ /**
387
+ * Refresh the agent's earnings snapshot when its backend supports doing so.
388
+ * Implementations own freshness and request-deduplication policy.
389
+ */
390
+ refreshEarnings?(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
386
391
  getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
387
392
  /**
388
393
  * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
@@ -581,6 +586,11 @@ declare class OwneySDK {
581
586
  * @returns {AgentEarnings} for a single agent, or {OwneyEarnings} with totalEarnings and per-agent breakdown
582
587
  */
583
588
  getEarnings(agentId?: AgentId): Promise<OwneyEarnings | AgentEarnings>;
589
+ /**
590
+ * Return refreshed earnings while letting each agent own its refresh policy.
591
+ * Agents without a refresh capability fall back to their current snapshot.
592
+ */
593
+ refreshEarnings(agentId?: AgentId): Promise<OwneyEarnings | AgentEarnings>;
584
594
  /**
585
595
  * Get the weighted APY for the user's account over a time period.
586
596
  * When querying all agents, the total APY is a balance-weighted average.
package/dist/index.d.ts CHANGED
@@ -383,6 +383,11 @@ interface IAgent {
383
383
  withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
384
384
  getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
385
385
  getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
386
+ /**
387
+ * Refresh the agent's earnings snapshot when its backend supports doing so.
388
+ * Implementations own freshness and request-deduplication policy.
389
+ */
390
+ refreshEarnings?(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
386
391
  getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays,
387
392
  /**
388
393
  * Optional asset symbol ("USDC" / "WETH") scoping the daily series to a
@@ -581,6 +586,11 @@ declare class OwneySDK {
581
586
  * @returns {AgentEarnings} for a single agent, or {OwneyEarnings} with totalEarnings and per-agent breakdown
582
587
  */
583
588
  getEarnings(agentId?: AgentId): Promise<OwneyEarnings | AgentEarnings>;
589
+ /**
590
+ * Return refreshed earnings while letting each agent own its refresh policy.
591
+ * Agents without a refresh capability fall back to their current snapshot.
592
+ */
593
+ refreshEarnings(agentId?: AgentId): Promise<OwneyEarnings | AgentEarnings>;
584
594
  /**
585
595
  * Get the weighted APY for the user's account over a time period.
586
596
  * When querying all agents, the total APY is a balance-weighted average.
package/dist/index.js CHANGED
@@ -838,6 +838,7 @@ var WETH_ADDRESS_BY_CHAIN = {
838
838
  var VIEM_CHAIN = { 8453: base, 42161: arbitrum, 1: mainnet };
839
839
  var SPLITTING_ASSETS = ["USDC", "WETH"];
840
840
  var POOL_POLICY_CHAIN_IDS = [8453, 42161, 1];
841
+ var EARNINGS_REFRESH_COOLDOWN_MS = 60 * 60 * 1e3;
841
842
  var ZyfaiAgent = class {
842
843
  id = "zyfai";
843
844
  supportedChainIds = [8453, 42161, 1];
@@ -889,6 +890,7 @@ var ZyfaiAgent = class {
889
890
  // successful decode is cached forever; failures are NOT cached so a transient
890
891
  // RPC error retries on the next fetch.
891
892
  withdrawAmountCache = /* @__PURE__ */ new Map();
893
+ earningsRefreshInFlight = null;
892
894
  constructor(apiKey, rpcUrls, referralSource) {
893
895
  this.rpcUrls = rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS;
894
896
  this.sdk = new ZyfaiSDK({
@@ -1686,6 +1688,22 @@ var ZyfaiAgent = class {
1686
1688
  const raw = await this.sdk.getOnchainEarnings(smartWallet);
1687
1689
  return mapEarnings(raw, smartWallet);
1688
1690
  }
1691
+ async refreshEarnings(state, chainId) {
1692
+ if (this.earningsRefreshInFlight) return this.earningsRefreshInFlight;
1693
+ this.earningsRefreshInFlight = (async () => {
1694
+ const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1695
+ const current = await this.sdk.getOnchainEarnings(smartWallet);
1696
+ const lastCheck = current.data.lastCheckTimestamp ? Date.parse(current.data.lastCheckTimestamp) : Number.NaN;
1697
+ const isFresh = Number.isFinite(lastCheck) && Date.now() - lastCheck < EARNINGS_REFRESH_COOLDOWN_MS;
1698
+ const earnings = isFresh ? current : await this.sdk.calculateOnchainEarnings(smartWallet);
1699
+ return mapEarnings(earnings, smartWallet);
1700
+ })();
1701
+ try {
1702
+ return await this.earningsRefreshInFlight;
1703
+ } finally {
1704
+ this.earningsRefreshInFlight = null;
1705
+ }
1706
+ }
1689
1707
  async getAccountApy(state, chainId, days, tokenSymbol) {
1690
1708
  const { smartWallet } = await this.resolveSmartWallet(state, chainId);
1691
1709
  const raw = await this.sdk.getDailyApyHistory(smartWallet, days);
@@ -3390,6 +3408,28 @@ var OwneySDK = class {
3390
3408
  agentEarnings: results
3391
3409
  };
3392
3410
  }
3411
+ /**
3412
+ * Return refreshed earnings while letting each agent own its refresh policy.
3413
+ * Agents without a refresh capability fall back to their current snapshot.
3414
+ */
3415
+ async refreshEarnings(agentId) {
3416
+ const state = this.requireState();
3417
+ const chainId = this.requireChainId();
3418
+ const refreshAgent = (agent) => agent.refreshEarnings?.(state, chainId) ?? agent.getEarnings(state, chainId);
3419
+ if (agentId) return refreshAgent(this.getAgent(agentId));
3420
+ let totalEarnings = 0;
3421
+ const agentEarnings = {};
3422
+ const refreshed = await Promise.all(
3423
+ [...this.getActiveAgents().entries()].map(
3424
+ async ([id, agent]) => [id, await refreshAgent(agent)]
3425
+ )
3426
+ );
3427
+ for (const [id, earnings] of refreshed) {
3428
+ agentEarnings[id] = earnings;
3429
+ totalEarnings += Number(earnings.lifetimeEarnings);
3430
+ }
3431
+ return { totalEarnings: String(totalEarnings), agentEarnings };
3432
+ }
3393
3433
  /**
3394
3434
  * Get the weighted APY for the user's account over a time period.
3395
3435
  * When querying all agents, the total APY is a balance-weighted average.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",