@owney/sdk 0.7.18 → 0.7.20

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
@@ -495,7 +495,7 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
495
495
  let totalBalance = 0;
496
496
  for (const p of entry.positions ?? []) {
497
497
  if (p.chainId !== chainId) continue;
498
- if (tokenSymbol && p.tokenSymbol !== tokenSymbol) continue;
498
+ if (tokenSymbol && p.tokenSymbol?.toUpperCase() !== tokenSymbol.toUpperCase()) continue;
499
499
  const balance = p.balance ?? 0;
500
500
  const apy = netApy(p.apy_withFee, p.apy, "apy_withFee");
501
501
  if (balance <= 0 || typeof apy !== "number") continue;
@@ -507,7 +507,18 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
507
507
  function mapApyHistory(raw, chainId, tokenSymbol) {
508
508
  const history = Object.entries(raw.history ?? {}).map(([date, entry]) => ({
509
509
  date,
510
- apy: rawPoolApyForChain(entry, chainId, tokenSymbol)
510
+ apy: rawPoolApyForChain(entry, chainId, tokenSymbol),
511
+ // Provider position balances are treated as decimal amounts of the
512
+ // selected token. Carry its unit dynamically for every asset; never
513
+ // attach a token unit to an unscoped mix of assets.
514
+ ...tokenSymbol ? {
515
+ historicalBalance: {
516
+ amount: (entry.positions ?? []).filter(
517
+ (p) => p.chainId === chainId && p.tokenSymbol?.toUpperCase() === tokenSymbol.toUpperCase() && Number.isFinite(p.balance) && p.balance > 0 && Number.isFinite(p.apy_withFee ?? p.apy)
518
+ ).reduce((sum, p) => sum + p.balance, 0),
519
+ unit: tokenSymbol.toUpperCase()
520
+ }
521
+ } : {}
511
522
  })).filter((p) => p.apy !== null).sort((a, b) => a.date.localeCompare(b.date));
512
523
  return {
513
524
  walletAddress: raw.walletAddress,
@@ -2223,6 +2234,46 @@ function sumWithdrawnAmount(results) {
2223
2234
  }
2224
2235
 
2225
2236
  // src/lib/helpers/account-apy-helper.ts
2237
+ function balanceForApyScope(balance, chainId, tokenSymbol) {
2238
+ if (!tokenSymbol) {
2239
+ const total = Number(balance.totalBalance);
2240
+ return Number.isFinite(total) && total > 0 ? total : 0;
2241
+ }
2242
+ const normalizedToken = tokenSymbol.toUpperCase();
2243
+ return balance.tokens.reduce((total, token) => {
2244
+ if (Number(token.chainId) !== chainId || String(token.asset).toUpperCase() !== normalizedToken) {
2245
+ return total;
2246
+ }
2247
+ const amount = Number(token.amount);
2248
+ return Number.isFinite(amount) && amount > 0 ? total + amount : total;
2249
+ }, 0);
2250
+ }
2251
+ function aggregateApyHistory(agentApys) {
2252
+ const byDate = /* @__PURE__ */ new Map();
2253
+ for (const accountApy of Object.values(agentApys)) {
2254
+ const seen = /* @__PURE__ */ new Set();
2255
+ for (const point of accountApy.history ?? []) {
2256
+ if (!point.date || seen.has(point.date) || !Number.isFinite(point.apy)) continue;
2257
+ seen.add(point.date);
2258
+ const points = byDate.get(point.date) ?? [];
2259
+ points.push(point);
2260
+ byDate.set(point.date, points);
2261
+ }
2262
+ }
2263
+ return [...byDate.entries()].sort(([left], [right]) => left.localeCompare(right)).flatMap(([date, points]) => {
2264
+ if (points.length === 1 && !points[0].historicalBalance) {
2265
+ return [{ date, apy: points[0].apy }];
2266
+ }
2267
+ const unit = points[0].historicalBalance?.unit;
2268
+ if (!unit || points.some(
2269
+ ({ historicalBalance: balance }) => !balance || balance.unit !== unit || !Number.isFinite(balance.amount) || balance.amount < 0
2270
+ )) return [];
2271
+ const total = points.reduce((sum, p) => sum + p.historicalBalance.amount, 0);
2272
+ if (total <= 0 || !Number.isFinite(total)) return [];
2273
+ const apy = points.reduce((sum, p) => sum + p.apy * (p.historicalBalance.amount / total), 0);
2274
+ return Number.isFinite(apy) ? [{ date, apy }] : [];
2275
+ });
2276
+ }
2226
2277
  function aggregateApyByChainAndAsset(agentApys, agentBalances) {
2227
2278
  const sums = {};
2228
2279
  const weights = {};
@@ -3893,7 +3944,7 @@ var OwneySDK = class {
3893
3944
  Promise.all(
3894
3945
  entries.map(async ([id, agent]) => {
3895
3946
  const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
3896
- return [id, Number(b.totalBalance)];
3947
+ return [id, balanceForApyScope(b, chainId, tokenSymbol)];
3897
3948
  })
3898
3949
  )
3899
3950
  ]);
@@ -3921,10 +3972,12 @@ var OwneySDK = class {
3921
3972
  }
3922
3973
  }
3923
3974
  const apyByChainAndAsset = aggregateApyByChainAndAsset(results, balances);
3975
+ const history = aggregateApyHistory(results);
3924
3976
  return {
3925
3977
  totalApy: String(totalApy),
3926
3978
  agentApy: results,
3927
- apyByChainAndAsset
3979
+ apyByChainAndAsset,
3980
+ history
3928
3981
  };
3929
3982
  }
3930
3983
  /**
package/dist/index.d.cts CHANGED
@@ -280,6 +280,11 @@ interface ApyHistoryPoint {
280
280
  date: string;
281
281
  /** Net (after-fee) weighted APY for that day, summed across tokens. */
282
282
  apy: number;
283
+ /** Balance on this date, in the explicitly named unit; never today's balance. */
284
+ historicalBalance?: {
285
+ amount: number;
286
+ unit: string;
287
+ };
283
288
  }
284
289
  interface AccountAgentApy {
285
290
  walletAddress: string;
@@ -296,6 +301,8 @@ interface OwneyAccountApy {
296
301
  totalApy: string;
297
302
  agentApy: Record<AgentId, AccountAgentApy>;
298
303
  apyByChainAndAsset: ApyByChainAndAsset;
304
+ /** APY weighted by same-date balances in matching units, independent of current balances. */
305
+ history?: ApyHistoryPoint[];
299
306
  }
300
307
  interface AllocationAgentApy {
301
308
  /** Account-wide weighted APY for this agent, as a decimal string. */
package/dist/index.d.ts CHANGED
@@ -280,6 +280,11 @@ interface ApyHistoryPoint {
280
280
  date: string;
281
281
  /** Net (after-fee) weighted APY for that day, summed across tokens. */
282
282
  apy: number;
283
+ /** Balance on this date, in the explicitly named unit; never today's balance. */
284
+ historicalBalance?: {
285
+ amount: number;
286
+ unit: string;
287
+ };
283
288
  }
284
289
  interface AccountAgentApy {
285
290
  walletAddress: string;
@@ -296,6 +301,8 @@ interface OwneyAccountApy {
296
301
  totalApy: string;
297
302
  agentApy: Record<AgentId, AccountAgentApy>;
298
303
  apyByChainAndAsset: ApyByChainAndAsset;
304
+ /** APY weighted by same-date balances in matching units, independent of current balances. */
305
+ history?: ApyHistoryPoint[];
299
306
  }
300
307
  interface AllocationAgentApy {
301
308
  /** Account-wide weighted APY for this agent, as a decimal string. */
package/dist/index.js CHANGED
@@ -462,7 +462,7 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
462
462
  let totalBalance = 0;
463
463
  for (const p of entry.positions ?? []) {
464
464
  if (p.chainId !== chainId) continue;
465
- if (tokenSymbol && p.tokenSymbol !== tokenSymbol) continue;
465
+ if (tokenSymbol && p.tokenSymbol?.toUpperCase() !== tokenSymbol.toUpperCase()) continue;
466
466
  const balance = p.balance ?? 0;
467
467
  const apy = netApy(p.apy_withFee, p.apy, "apy_withFee");
468
468
  if (balance <= 0 || typeof apy !== "number") continue;
@@ -474,7 +474,18 @@ function rawPoolApyForChain(entry, chainId, tokenSymbol) {
474
474
  function mapApyHistory(raw, chainId, tokenSymbol) {
475
475
  const history = Object.entries(raw.history ?? {}).map(([date, entry]) => ({
476
476
  date,
477
- apy: rawPoolApyForChain(entry, chainId, tokenSymbol)
477
+ apy: rawPoolApyForChain(entry, chainId, tokenSymbol),
478
+ // Provider position balances are treated as decimal amounts of the
479
+ // selected token. Carry its unit dynamically for every asset; never
480
+ // attach a token unit to an unscoped mix of assets.
481
+ ...tokenSymbol ? {
482
+ historicalBalance: {
483
+ amount: (entry.positions ?? []).filter(
484
+ (p) => p.chainId === chainId && p.tokenSymbol?.toUpperCase() === tokenSymbol.toUpperCase() && Number.isFinite(p.balance) && p.balance > 0 && Number.isFinite(p.apy_withFee ?? p.apy)
485
+ ).reduce((sum, p) => sum + p.balance, 0),
486
+ unit: tokenSymbol.toUpperCase()
487
+ }
488
+ } : {}
478
489
  })).filter((p) => p.apy !== null).sort((a, b) => a.date.localeCompare(b.date));
479
490
  return {
480
491
  walletAddress: raw.walletAddress,
@@ -2190,6 +2201,46 @@ function sumWithdrawnAmount(results) {
2190
2201
  }
2191
2202
 
2192
2203
  // src/lib/helpers/account-apy-helper.ts
2204
+ function balanceForApyScope(balance, chainId, tokenSymbol) {
2205
+ if (!tokenSymbol) {
2206
+ const total = Number(balance.totalBalance);
2207
+ return Number.isFinite(total) && total > 0 ? total : 0;
2208
+ }
2209
+ const normalizedToken = tokenSymbol.toUpperCase();
2210
+ return balance.tokens.reduce((total, token) => {
2211
+ if (Number(token.chainId) !== chainId || String(token.asset).toUpperCase() !== normalizedToken) {
2212
+ return total;
2213
+ }
2214
+ const amount = Number(token.amount);
2215
+ return Number.isFinite(amount) && amount > 0 ? total + amount : total;
2216
+ }, 0);
2217
+ }
2218
+ function aggregateApyHistory(agentApys) {
2219
+ const byDate = /* @__PURE__ */ new Map();
2220
+ for (const accountApy of Object.values(agentApys)) {
2221
+ const seen = /* @__PURE__ */ new Set();
2222
+ for (const point of accountApy.history ?? []) {
2223
+ if (!point.date || seen.has(point.date) || !Number.isFinite(point.apy)) continue;
2224
+ seen.add(point.date);
2225
+ const points = byDate.get(point.date) ?? [];
2226
+ points.push(point);
2227
+ byDate.set(point.date, points);
2228
+ }
2229
+ }
2230
+ return [...byDate.entries()].sort(([left], [right]) => left.localeCompare(right)).flatMap(([date, points]) => {
2231
+ if (points.length === 1 && !points[0].historicalBalance) {
2232
+ return [{ date, apy: points[0].apy }];
2233
+ }
2234
+ const unit = points[0].historicalBalance?.unit;
2235
+ if (!unit || points.some(
2236
+ ({ historicalBalance: balance }) => !balance || balance.unit !== unit || !Number.isFinite(balance.amount) || balance.amount < 0
2237
+ )) return [];
2238
+ const total = points.reduce((sum, p) => sum + p.historicalBalance.amount, 0);
2239
+ if (total <= 0 || !Number.isFinite(total)) return [];
2240
+ const apy = points.reduce((sum, p) => sum + p.apy * (p.historicalBalance.amount / total), 0);
2241
+ return Number.isFinite(apy) ? [{ date, apy }] : [];
2242
+ });
2243
+ }
2193
2244
  function aggregateApyByChainAndAsset(agentApys, agentBalances) {
2194
2245
  const sums = {};
2195
2246
  const weights = {};
@@ -3864,7 +3915,7 @@ var OwneySDK = class {
3864
3915
  Promise.all(
3865
3916
  entries.map(async ([id, agent]) => {
3866
3917
  const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
3867
- return [id, Number(b.totalBalance)];
3918
+ return [id, balanceForApyScope(b, chainId, tokenSymbol)];
3868
3919
  })
3869
3920
  )
3870
3921
  ]);
@@ -3892,10 +3943,12 @@ var OwneySDK = class {
3892
3943
  }
3893
3944
  }
3894
3945
  const apyByChainAndAsset = aggregateApyByChainAndAsset(results, balances);
3946
+ const history = aggregateApyHistory(results);
3895
3947
  return {
3896
3948
  totalApy: String(totalApy),
3897
3949
  agentApy: results,
3898
- apyByChainAndAsset
3950
+ apyByChainAndAsset,
3951
+ history
3899
3952
  };
3900
3953
  }
3901
3954
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.18",
3
+ "version": "0.7.20",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",