@owney/sdk 0.7.25-beta.18 → 0.7.25-beta.19
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 +86 -19
- package/dist/index.d.cts +14 -14
- package/dist/index.d.ts +14 -14
- package/dist/index.js +86 -19
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3769,6 +3769,35 @@ function mapYieldseekerEarnings(contexts) {
|
|
|
3769
3769
|
tokens
|
|
3770
3770
|
};
|
|
3771
3771
|
}
|
|
3772
|
+
function mapYieldseekerDailyEarnings(walletAddress, contexts, days, now = Date.now()) {
|
|
3773
|
+
const today = new Date(now).toISOString().slice(0, 10);
|
|
3774
|
+
const dayCount = { "7D": 7, "14D": 14, "30D": 30 }[days];
|
|
3775
|
+
const cutoff = new Date(Date.parse(today) - dayCount * 864e5).toISOString().slice(0, 10);
|
|
3776
|
+
const assets = contexts.flatMap((context) => {
|
|
3777
|
+
const snapshots = context.historic?.dailyYieldSnapshots;
|
|
3778
|
+
if (!Array.isArray(snapshots)) invalid("historic position", "missing daily yield snapshots");
|
|
3779
|
+
const byDate = /* @__PURE__ */ new Map();
|
|
3780
|
+
for (const snapshot of snapshots) {
|
|
3781
|
+
const time = Date.parse(snapshot.date);
|
|
3782
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(snapshot.date) || !Number.isFinite(time) || new Date(time).toISOString().slice(0, 10) !== snapshot.date) {
|
|
3783
|
+
invalid("historic position", "expected a UTC snapshot date");
|
|
3784
|
+
}
|
|
3785
|
+
if (snapshot.date > today) continue;
|
|
3786
|
+
if (snapshot.baseAssetDecimals !== YIELDSEEKER_ASSET_METADATA[context.asset].decimals) {
|
|
3787
|
+
invalid("historic position", "base asset decimals do not match the selected asset");
|
|
3788
|
+
}
|
|
3789
|
+
const amount = Number(decimal(snapshot.cumulativeYieldBase, snapshot.baseAssetDecimals, "historic position"));
|
|
3790
|
+
if (!Number.isFinite(amount)) invalid("historic position", "expected finite cumulative yield");
|
|
3791
|
+
byDate.set(snapshot.date, { date: snapshot.date, amount });
|
|
3792
|
+
}
|
|
3793
|
+
const sorted = [...byDate.values()].sort((a, b) => a.date.localeCompare(b.date));
|
|
3794
|
+
const window2 = sorted.filter((point) => point.date >= cutoff);
|
|
3795
|
+
if (!window2.length) return [];
|
|
3796
|
+
const opening = sorted.filter((point) => point.date < cutoff).at(-1);
|
|
3797
|
+
return [{ asset: context.asset, points: opening ? [opening, ...window2] : window2 }];
|
|
3798
|
+
}).sort((a, b) => a.asset.localeCompare(b.asset));
|
|
3799
|
+
return { walletAddress, chainId: 8453, assets };
|
|
3800
|
+
}
|
|
3772
3801
|
function apyForDays(context, days, now) {
|
|
3773
3802
|
if (days === "7D") return percent(context.snapshot.apy7d);
|
|
3774
3803
|
if (days === "30D") return percent(context.snapshot.apy30d);
|
|
@@ -6110,6 +6139,17 @@ var YieldseekerAgent = class {
|
|
|
6110
6139
|
});
|
|
6111
6140
|
return mapYieldseekerApy(state.walletAddress, contexts, days);
|
|
6112
6141
|
}
|
|
6142
|
+
async getDailyEarnings(state, chainId, days, tokenSymbol) {
|
|
6143
|
+
this.assertChain(chainId);
|
|
6144
|
+
const asset = tokenSymbol?.toUpperCase();
|
|
6145
|
+
if (asset !== void 0) this.assertAsset(asset);
|
|
6146
|
+
const contexts = await this.loadActivityPortfolio(state, chainId, {
|
|
6147
|
+
...asset ? { asset } : {},
|
|
6148
|
+
historic: true,
|
|
6149
|
+
includePositions: false
|
|
6150
|
+
});
|
|
6151
|
+
return mapYieldseekerDailyEarnings(state.walletAddress, contexts, days);
|
|
6152
|
+
}
|
|
6113
6153
|
async getHistory(state, chainId, options) {
|
|
6114
6154
|
this.assertChain(chainId);
|
|
6115
6155
|
const asset = options?.tokenSymbol?.toUpperCase();
|
|
@@ -6620,7 +6660,7 @@ var YieldseekerAgent = class {
|
|
|
6620
6660
|
}
|
|
6621
6661
|
async loadPortfolioParts(state, chainId, context, options, contextKey) {
|
|
6622
6662
|
const [positions, historic, actions] = await Promise.all([
|
|
6623
|
-
this.cachedRead(
|
|
6663
|
+
options.includePositions === false ? Promise.resolve({ yieldPositions: [] }) : this.cachedRead(
|
|
6624
6664
|
`positions:${contextKey}`,
|
|
6625
6665
|
this.portfolioCacheMs(contextKey),
|
|
6626
6666
|
async () => {
|
|
@@ -7243,6 +7283,43 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
7243
7283
|
return out;
|
|
7244
7284
|
}
|
|
7245
7285
|
|
|
7286
|
+
// src/lib/helpers/daily-earnings-helper.ts
|
|
7287
|
+
function aggregateDailyEarnings(series, tokenSymbol) {
|
|
7288
|
+
const wanted = tokenSymbol?.toUpperCase();
|
|
7289
|
+
const byAsset = /* @__PURE__ */ new Map();
|
|
7290
|
+
for (const account of series) {
|
|
7291
|
+
for (const { asset, points } of account.assets) {
|
|
7292
|
+
const symbol = asset.toUpperCase();
|
|
7293
|
+
if (!points.length || wanted && symbol !== wanted) continue;
|
|
7294
|
+
const components = byAsset.get(symbol) ?? [];
|
|
7295
|
+
components.push([...points].sort((a, b) => a.date.localeCompare(b.date)));
|
|
7296
|
+
byAsset.set(symbol, components);
|
|
7297
|
+
}
|
|
7298
|
+
}
|
|
7299
|
+
return [...byAsset.entries()].map(([asset, components]) => {
|
|
7300
|
+
const dates = [...new Set(components.flatMap((points2) => points2.map((point) => point.date)))].sort();
|
|
7301
|
+
const cursors = components.map((points2) => ({
|
|
7302
|
+
index: 0,
|
|
7303
|
+
// Providers can have different lifetime/window offsets and start dates.
|
|
7304
|
+
// Remove each opening reading before combining their earned amounts.
|
|
7305
|
+
baseline: points2[0].amount,
|
|
7306
|
+
current: points2[0].amount
|
|
7307
|
+
}));
|
|
7308
|
+
const points = dates.map((date) => {
|
|
7309
|
+
let amount = 0;
|
|
7310
|
+
components.forEach((component, index) => {
|
|
7311
|
+
const cursor = cursors[index];
|
|
7312
|
+
while (cursor.index < component.length && component[cursor.index].date <= date) {
|
|
7313
|
+
cursor.current = component[cursor.index++].amount;
|
|
7314
|
+
}
|
|
7315
|
+
amount += cursor.current - cursor.baseline;
|
|
7316
|
+
});
|
|
7317
|
+
return { date, amount };
|
|
7318
|
+
});
|
|
7319
|
+
return { asset, points };
|
|
7320
|
+
}).sort((a, b) => a.asset.localeCompare(b.asset));
|
|
7321
|
+
}
|
|
7322
|
+
|
|
7246
7323
|
// src/client.ts
|
|
7247
7324
|
var import_viem17 = require("viem");
|
|
7248
7325
|
var import_chains5 = require("viem/chains");
|
|
@@ -9625,10 +9702,8 @@ var OwneySDK = class {
|
|
|
9625
9702
|
* @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
|
|
9626
9703
|
*/
|
|
9627
9704
|
/**
|
|
9628
|
-
* Daily cumulative
|
|
9629
|
-
* "recent earnings" subline.
|
|
9630
|
-
* `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
|
|
9631
|
-
* balance headline rather than reading ~11% high. (ROUT-452)
|
|
9705
|
+
* Daily cumulative earnings in the selected asset's units, backing the
|
|
9706
|
+
* "recent earnings" subline. Each adapter uses its provider's earnings basis.
|
|
9632
9707
|
*
|
|
9633
9708
|
* Unlike getAccountApy this does NOT blend across agents: earnings are
|
|
9634
9709
|
* summed, not weighted, and an agent that fails to report must not silently
|
|
@@ -9661,7 +9736,7 @@ var OwneySDK = class {
|
|
|
9661
9736
|
const entries = [...this.getActiveAgents().entries()].filter(
|
|
9662
9737
|
([, agent]) => agent.getDailyEarnings
|
|
9663
9738
|
);
|
|
9664
|
-
const
|
|
9739
|
+
const settled = await Promise.allSettled(
|
|
9665
9740
|
entries.map(
|
|
9666
9741
|
([, agent]) => this.readAgent(
|
|
9667
9742
|
agent,
|
|
@@ -9671,23 +9746,15 @@ var OwneySDK = class {
|
|
|
9671
9746
|
)
|
|
9672
9747
|
)
|
|
9673
9748
|
);
|
|
9674
|
-
const
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
for (const point of points) {
|
|
9679
|
-
byDate.set(point.date, (byDate.get(point.date) ?? 0) + point.amount);
|
|
9680
|
-
}
|
|
9681
|
-
byAsset.set(asset, byDate);
|
|
9682
|
-
}
|
|
9749
|
+
const series = settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
|
|
9750
|
+
if (entries.length && !series.length) {
|
|
9751
|
+
const failure = settled.find((result) => result.status === "rejected");
|
|
9752
|
+
if (failure?.status === "rejected") throw failure.reason;
|
|
9683
9753
|
}
|
|
9684
9754
|
return {
|
|
9685
9755
|
walletAddress: series[0]?.walletAddress ?? state.walletAddress ?? "",
|
|
9686
9756
|
chainId,
|
|
9687
|
-
assets:
|
|
9688
|
-
asset,
|
|
9689
|
-
points: [...byDate.entries()].map(([date, amount]) => ({ date, amount })).sort((a, b) => a.date.localeCompare(b.date))
|
|
9690
|
-
})).sort((a, b) => a.asset.localeCompare(b.asset))
|
|
9757
|
+
assets: aggregateDailyEarnings(series, tokenSymbol)
|
|
9691
9758
|
};
|
|
9692
9759
|
}
|
|
9693
9760
|
async getAccountApy({
|
package/dist/index.d.cts
CHANGED
|
@@ -169,9 +169,9 @@ interface IAgent {
|
|
|
169
169
|
*/
|
|
170
170
|
tokenSymbol?: string): Promise<AccountAgentApy>;
|
|
171
171
|
/**
|
|
172
|
-
* Daily cumulative
|
|
173
|
-
*
|
|
174
|
-
*
|
|
172
|
+
* Daily cumulative earnings in token units, scoped to a chain/asset, using
|
|
173
|
+
* the provider's earnings basis. Include an opening snapshot when available
|
|
174
|
+
* so the "recent earnings" subline can difference the endpoints. (ROUT-452)
|
|
175
175
|
*/
|
|
176
176
|
getDailyEarnings?(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
|
|
177
177
|
getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
|
|
@@ -658,15 +658,15 @@ interface AgentApy {
|
|
|
658
658
|
interface OwneyAgentApy {
|
|
659
659
|
agentApy: Record<AgentId, AgentApy>;
|
|
660
660
|
}
|
|
661
|
-
/** One day's cumulative
|
|
661
|
+
/** One day's cumulative earnings for a single asset. */
|
|
662
662
|
interface DailyEarningsPoint {
|
|
663
663
|
/** ISO date string for the day, e.g. "2026-09-01". */
|
|
664
664
|
date: string;
|
|
665
665
|
/**
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
666
|
+
* Cumulative earnings in the asset's own units, using the provider's earnings
|
|
667
|
+
* basis. A provider may return lifetime totals or a running window total;
|
|
668
|
+
* difference the last and opening points to measure earnings over the window.
|
|
669
|
+
* Aggregate series normalize each component's opening value before summing.
|
|
670
670
|
*/
|
|
671
671
|
amount: number;
|
|
672
672
|
}
|
|
@@ -675,8 +675,9 @@ interface AssetDailyEarnings {
|
|
|
675
675
|
/** Asset symbol, e.g. "USDC" / "WETH". */
|
|
676
676
|
asset: string;
|
|
677
677
|
/**
|
|
678
|
-
* Ascending by date
|
|
679
|
-
*
|
|
678
|
+
* Ascending by date, including an opening snapshot before the requested
|
|
679
|
+
* window when available. Provider gaps remain absent; aggregates carry the
|
|
680
|
+
* most recent cumulative value across dates reported by other providers.
|
|
680
681
|
*/
|
|
681
682
|
points: DailyEarningsPoint[];
|
|
682
683
|
}
|
|
@@ -954,10 +955,8 @@ declare class OwneySDK {
|
|
|
954
955
|
* @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
|
|
955
956
|
*/
|
|
956
957
|
/**
|
|
957
|
-
* Daily cumulative
|
|
958
|
-
* "recent earnings" subline.
|
|
959
|
-
* `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
|
|
960
|
-
* balance headline rather than reading ~11% high. (ROUT-452)
|
|
958
|
+
* Daily cumulative earnings in the selected asset's units, backing the
|
|
959
|
+
* "recent earnings" subline. Each adapter uses its provider's earnings basis.
|
|
961
960
|
*
|
|
962
961
|
* Unlike getAccountApy this does NOT blend across agents: earnings are
|
|
963
962
|
* summed, not weighted, and an agent that fails to report must not silently
|
|
@@ -1146,6 +1145,7 @@ declare class YieldseekerAgent implements IAgent {
|
|
|
1146
1145
|
hasExistingDepositFunds(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<true | undefined>;
|
|
1147
1146
|
getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
|
|
1148
1147
|
getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays, tokenSymbol?: string): Promise<AccountAgentApy>;
|
|
1148
|
+
getDailyEarnings(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
|
|
1149
1149
|
getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
|
|
1150
1150
|
getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
|
|
1151
1151
|
getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
|
package/dist/index.d.ts
CHANGED
|
@@ -169,9 +169,9 @@ interface IAgent {
|
|
|
169
169
|
*/
|
|
170
170
|
tokenSymbol?: string): Promise<AccountAgentApy>;
|
|
171
171
|
/**
|
|
172
|
-
* Daily cumulative
|
|
173
|
-
*
|
|
174
|
-
*
|
|
172
|
+
* Daily cumulative earnings in token units, scoped to a chain/asset, using
|
|
173
|
+
* the provider's earnings basis. Include an opening snapshot when available
|
|
174
|
+
* so the "recent earnings" subline can difference the endpoints. (ROUT-452)
|
|
175
175
|
*/
|
|
176
176
|
getDailyEarnings?(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
|
|
177
177
|
getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
|
|
@@ -658,15 +658,15 @@ interface AgentApy {
|
|
|
658
658
|
interface OwneyAgentApy {
|
|
659
659
|
agentApy: Record<AgentId, AgentApy>;
|
|
660
660
|
}
|
|
661
|
-
/** One day's cumulative
|
|
661
|
+
/** One day's cumulative earnings for a single asset. */
|
|
662
662
|
interface DailyEarningsPoint {
|
|
663
663
|
/** ISO date string for the day, e.g. "2026-09-01". */
|
|
664
664
|
date: string;
|
|
665
665
|
/**
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
666
|
+
* Cumulative earnings in the asset's own units, using the provider's earnings
|
|
667
|
+
* basis. A provider may return lifetime totals or a running window total;
|
|
668
|
+
* difference the last and opening points to measure earnings over the window.
|
|
669
|
+
* Aggregate series normalize each component's opening value before summing.
|
|
670
670
|
*/
|
|
671
671
|
amount: number;
|
|
672
672
|
}
|
|
@@ -675,8 +675,9 @@ interface AssetDailyEarnings {
|
|
|
675
675
|
/** Asset symbol, e.g. "USDC" / "WETH". */
|
|
676
676
|
asset: string;
|
|
677
677
|
/**
|
|
678
|
-
* Ascending by date
|
|
679
|
-
*
|
|
678
|
+
* Ascending by date, including an opening snapshot before the requested
|
|
679
|
+
* window when available. Provider gaps remain absent; aggregates carry the
|
|
680
|
+
* most recent cumulative value across dates reported by other providers.
|
|
680
681
|
*/
|
|
681
682
|
points: DailyEarningsPoint[];
|
|
682
683
|
}
|
|
@@ -954,10 +955,8 @@ declare class OwneySDK {
|
|
|
954
955
|
* @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
|
|
955
956
|
*/
|
|
956
957
|
/**
|
|
957
|
-
* Daily cumulative
|
|
958
|
-
* "recent earnings" subline.
|
|
959
|
-
* `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
|
|
960
|
-
* balance headline rather than reading ~11% high. (ROUT-452)
|
|
958
|
+
* Daily cumulative earnings in the selected asset's units, backing the
|
|
959
|
+
* "recent earnings" subline. Each adapter uses its provider's earnings basis.
|
|
961
960
|
*
|
|
962
961
|
* Unlike getAccountApy this does NOT blend across agents: earnings are
|
|
963
962
|
* summed, not weighted, and an agent that fails to report must not silently
|
|
@@ -1146,6 +1145,7 @@ declare class YieldseekerAgent implements IAgent {
|
|
|
1146
1145
|
hasExistingDepositFunds(state: ConnectionState, chainId: number, asset: OwneySupportedTokens): Promise<true | undefined>;
|
|
1147
1146
|
getEarnings(state: ConnectionState, chainId: number): Promise<AgentEarnings>;
|
|
1148
1147
|
getAccountApy(state: ConnectionState, chainId: number, days: DailyApyDays, tokenSymbol?: string): Promise<AccountAgentApy>;
|
|
1148
|
+
getDailyEarnings(state: ConnectionState, chainId: number, days: LookbackDays, tokenSymbol?: string): Promise<AccountDailyEarnings>;
|
|
1149
1149
|
getHistory(state: ConnectionState, chainId: number, options?: HistoryFilters): Promise<OwneyAgentHistory>;
|
|
1150
1150
|
getUserProfile(state: ConnectionState, chainId: number): Promise<AgentUserProfile>;
|
|
1151
1151
|
getAgentApy(days: DailyApyDays, options?: AgentApyOptions): Promise<AgentApy>;
|
package/dist/index.js
CHANGED
|
@@ -3755,6 +3755,35 @@ function mapYieldseekerEarnings(contexts) {
|
|
|
3755
3755
|
tokens
|
|
3756
3756
|
};
|
|
3757
3757
|
}
|
|
3758
|
+
function mapYieldseekerDailyEarnings(walletAddress, contexts, days, now = Date.now()) {
|
|
3759
|
+
const today = new Date(now).toISOString().slice(0, 10);
|
|
3760
|
+
const dayCount = { "7D": 7, "14D": 14, "30D": 30 }[days];
|
|
3761
|
+
const cutoff = new Date(Date.parse(today) - dayCount * 864e5).toISOString().slice(0, 10);
|
|
3762
|
+
const assets = contexts.flatMap((context) => {
|
|
3763
|
+
const snapshots = context.historic?.dailyYieldSnapshots;
|
|
3764
|
+
if (!Array.isArray(snapshots)) invalid("historic position", "missing daily yield snapshots");
|
|
3765
|
+
const byDate = /* @__PURE__ */ new Map();
|
|
3766
|
+
for (const snapshot of snapshots) {
|
|
3767
|
+
const time = Date.parse(snapshot.date);
|
|
3768
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(snapshot.date) || !Number.isFinite(time) || new Date(time).toISOString().slice(0, 10) !== snapshot.date) {
|
|
3769
|
+
invalid("historic position", "expected a UTC snapshot date");
|
|
3770
|
+
}
|
|
3771
|
+
if (snapshot.date > today) continue;
|
|
3772
|
+
if (snapshot.baseAssetDecimals !== YIELDSEEKER_ASSET_METADATA[context.asset].decimals) {
|
|
3773
|
+
invalid("historic position", "base asset decimals do not match the selected asset");
|
|
3774
|
+
}
|
|
3775
|
+
const amount = Number(decimal(snapshot.cumulativeYieldBase, snapshot.baseAssetDecimals, "historic position"));
|
|
3776
|
+
if (!Number.isFinite(amount)) invalid("historic position", "expected finite cumulative yield");
|
|
3777
|
+
byDate.set(snapshot.date, { date: snapshot.date, amount });
|
|
3778
|
+
}
|
|
3779
|
+
const sorted = [...byDate.values()].sort((a, b) => a.date.localeCompare(b.date));
|
|
3780
|
+
const window2 = sorted.filter((point) => point.date >= cutoff);
|
|
3781
|
+
if (!window2.length) return [];
|
|
3782
|
+
const opening = sorted.filter((point) => point.date < cutoff).at(-1);
|
|
3783
|
+
return [{ asset: context.asset, points: opening ? [opening, ...window2] : window2 }];
|
|
3784
|
+
}).sort((a, b) => a.asset.localeCompare(b.asset));
|
|
3785
|
+
return { walletAddress, chainId: 8453, assets };
|
|
3786
|
+
}
|
|
3758
3787
|
function apyForDays(context, days, now) {
|
|
3759
3788
|
if (days === "7D") return percent(context.snapshot.apy7d);
|
|
3760
3789
|
if (days === "30D") return percent(context.snapshot.apy30d);
|
|
@@ -6105,6 +6134,17 @@ var YieldseekerAgent = class {
|
|
|
6105
6134
|
});
|
|
6106
6135
|
return mapYieldseekerApy(state.walletAddress, contexts, days);
|
|
6107
6136
|
}
|
|
6137
|
+
async getDailyEarnings(state, chainId, days, tokenSymbol) {
|
|
6138
|
+
this.assertChain(chainId);
|
|
6139
|
+
const asset = tokenSymbol?.toUpperCase();
|
|
6140
|
+
if (asset !== void 0) this.assertAsset(asset);
|
|
6141
|
+
const contexts = await this.loadActivityPortfolio(state, chainId, {
|
|
6142
|
+
...asset ? { asset } : {},
|
|
6143
|
+
historic: true,
|
|
6144
|
+
includePositions: false
|
|
6145
|
+
});
|
|
6146
|
+
return mapYieldseekerDailyEarnings(state.walletAddress, contexts, days);
|
|
6147
|
+
}
|
|
6108
6148
|
async getHistory(state, chainId, options) {
|
|
6109
6149
|
this.assertChain(chainId);
|
|
6110
6150
|
const asset = options?.tokenSymbol?.toUpperCase();
|
|
@@ -6615,7 +6655,7 @@ var YieldseekerAgent = class {
|
|
|
6615
6655
|
}
|
|
6616
6656
|
async loadPortfolioParts(state, chainId, context, options, contextKey) {
|
|
6617
6657
|
const [positions, historic, actions] = await Promise.all([
|
|
6618
|
-
this.cachedRead(
|
|
6658
|
+
options.includePositions === false ? Promise.resolve({ yieldPositions: [] }) : this.cachedRead(
|
|
6619
6659
|
`positions:${contextKey}`,
|
|
6620
6660
|
this.portfolioCacheMs(contextKey),
|
|
6621
6661
|
async () => {
|
|
@@ -7238,6 +7278,43 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
7238
7278
|
return out;
|
|
7239
7279
|
}
|
|
7240
7280
|
|
|
7281
|
+
// src/lib/helpers/daily-earnings-helper.ts
|
|
7282
|
+
function aggregateDailyEarnings(series, tokenSymbol) {
|
|
7283
|
+
const wanted = tokenSymbol?.toUpperCase();
|
|
7284
|
+
const byAsset = /* @__PURE__ */ new Map();
|
|
7285
|
+
for (const account of series) {
|
|
7286
|
+
for (const { asset, points } of account.assets) {
|
|
7287
|
+
const symbol = asset.toUpperCase();
|
|
7288
|
+
if (!points.length || wanted && symbol !== wanted) continue;
|
|
7289
|
+
const components = byAsset.get(symbol) ?? [];
|
|
7290
|
+
components.push([...points].sort((a, b) => a.date.localeCompare(b.date)));
|
|
7291
|
+
byAsset.set(symbol, components);
|
|
7292
|
+
}
|
|
7293
|
+
}
|
|
7294
|
+
return [...byAsset.entries()].map(([asset, components]) => {
|
|
7295
|
+
const dates = [...new Set(components.flatMap((points2) => points2.map((point) => point.date)))].sort();
|
|
7296
|
+
const cursors = components.map((points2) => ({
|
|
7297
|
+
index: 0,
|
|
7298
|
+
// Providers can have different lifetime/window offsets and start dates.
|
|
7299
|
+
// Remove each opening reading before combining their earned amounts.
|
|
7300
|
+
baseline: points2[0].amount,
|
|
7301
|
+
current: points2[0].amount
|
|
7302
|
+
}));
|
|
7303
|
+
const points = dates.map((date) => {
|
|
7304
|
+
let amount = 0;
|
|
7305
|
+
components.forEach((component, index) => {
|
|
7306
|
+
const cursor = cursors[index];
|
|
7307
|
+
while (cursor.index < component.length && component[cursor.index].date <= date) {
|
|
7308
|
+
cursor.current = component[cursor.index++].amount;
|
|
7309
|
+
}
|
|
7310
|
+
amount += cursor.current - cursor.baseline;
|
|
7311
|
+
});
|
|
7312
|
+
return { date, amount };
|
|
7313
|
+
});
|
|
7314
|
+
return { asset, points };
|
|
7315
|
+
}).sort((a, b) => a.asset.localeCompare(b.asset));
|
|
7316
|
+
}
|
|
7317
|
+
|
|
7241
7318
|
// src/client.ts
|
|
7242
7319
|
import {
|
|
7243
7320
|
parseUnits as parseUnits3,
|
|
@@ -9629,10 +9706,8 @@ var OwneySDK = class {
|
|
|
9629
9706
|
* @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
|
|
9630
9707
|
*/
|
|
9631
9708
|
/**
|
|
9632
|
-
* Daily cumulative
|
|
9633
|
-
* "recent earnings" subline.
|
|
9634
|
-
* `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
|
|
9635
|
-
* balance headline rather than reading ~11% high. (ROUT-452)
|
|
9709
|
+
* Daily cumulative earnings in the selected asset's units, backing the
|
|
9710
|
+
* "recent earnings" subline. Each adapter uses its provider's earnings basis.
|
|
9636
9711
|
*
|
|
9637
9712
|
* Unlike getAccountApy this does NOT blend across agents: earnings are
|
|
9638
9713
|
* summed, not weighted, and an agent that fails to report must not silently
|
|
@@ -9665,7 +9740,7 @@ var OwneySDK = class {
|
|
|
9665
9740
|
const entries = [...this.getActiveAgents().entries()].filter(
|
|
9666
9741
|
([, agent]) => agent.getDailyEarnings
|
|
9667
9742
|
);
|
|
9668
|
-
const
|
|
9743
|
+
const settled = await Promise.allSettled(
|
|
9669
9744
|
entries.map(
|
|
9670
9745
|
([, agent]) => this.readAgent(
|
|
9671
9746
|
agent,
|
|
@@ -9675,23 +9750,15 @@ var OwneySDK = class {
|
|
|
9675
9750
|
)
|
|
9676
9751
|
)
|
|
9677
9752
|
);
|
|
9678
|
-
const
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
for (const point of points) {
|
|
9683
|
-
byDate.set(point.date, (byDate.get(point.date) ?? 0) + point.amount);
|
|
9684
|
-
}
|
|
9685
|
-
byAsset.set(asset, byDate);
|
|
9686
|
-
}
|
|
9753
|
+
const series = settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
|
|
9754
|
+
if (entries.length && !series.length) {
|
|
9755
|
+
const failure = settled.find((result) => result.status === "rejected");
|
|
9756
|
+
if (failure?.status === "rejected") throw failure.reason;
|
|
9687
9757
|
}
|
|
9688
9758
|
return {
|
|
9689
9759
|
walletAddress: series[0]?.walletAddress ?? state.walletAddress ?? "",
|
|
9690
9760
|
chainId,
|
|
9691
|
-
assets:
|
|
9692
|
-
asset,
|
|
9693
|
-
points: [...byDate.entries()].map(([date, amount]) => ({ date, amount })).sort((a, b) => a.date.localeCompare(b.date))
|
|
9694
|
-
})).sort((a, b) => a.asset.localeCompare(b.asset))
|
|
9761
|
+
assets: aggregateDailyEarnings(series, tokenSymbol)
|
|
9695
9762
|
};
|
|
9696
9763
|
}
|
|
9697
9764
|
async getAccountApy({
|