@kasufinance/kasu-sdk 2.10.3 → 2.12.0
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 +28 -1
- package/dist/bundle.cjs.js +752 -59
- package/dist/bundle.esm.js +750 -60
- package/dist/domain/index.d.ts +10 -2
- package/dist/domain/index.js +6 -0
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/strategy-summary.d.ts +47 -0
- package/dist/domain/strategy-summary.js +76 -0
- package/dist/domain/strategy-summary.js.map +1 -0
- package/dist/domain/yield-history.d.ts +122 -0
- package/dist/domain/yield-history.js +95 -0
- package/dist/domain/yield-history.js.map +1 -0
- package/dist/facade/strategies.js +2 -0
- package/dist/facade/strategies.js.map +1 -1
- package/dist/facade/types.d.ts +13 -0
- package/dist/facade/user-portfolio.d.ts +32 -0
- package/dist/facade/user-portfolio.js +34 -0
- package/dist/facade/user-portfolio.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js.map +1 -1
- package/dist/services/Portfolio/portfolio.d.ts +37 -0
- package/dist/services/Portfolio/portfolio.js +136 -56
- package/dist/services/Portfolio/portfolio.js.map +1 -1
- package/dist/services/Portfolio/queries.js +15 -3
- package/dist/services/Portfolio/queries.js.map +1 -1
- package/dist/services/Portfolio/types.d.ts +8 -0
- package/dist/services/Portfolio/yield-history.d.ts +177 -0
- package/dist/services/Portfolio/yield-history.js +405 -0
- package/dist/services/Portfolio/yield-history.js.map +1 -0
- package/package.json +2 -1
- package/src/domain/index.ts +19 -10
- package/src/domain/strategy-summary.ts +88 -0
- package/src/domain/yield-history.ts +194 -0
- package/src/facade/strategies.ts +2 -0
- package/src/facade/types.ts +13 -0
- package/src/facade/user-portfolio.ts +40 -3
- package/src/index.ts +2 -0
- package/src/services/Portfolio/portfolio.ts +263 -153
- package/src/services/Portfolio/queries.ts +15 -3
- package/src/services/Portfolio/types.ts +10 -0
- package/src/services/Portfolio/yield-history.ts +574 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A strategy's SHORT blurb, as plain text: the CMS `liteDescription` first,
|
|
3
|
+
* else the first paragraph of the long `description`, else nothing.
|
|
4
|
+
*
|
|
5
|
+
* Lifted from kasu-ui (`pickShortDescription`, its deposit dialog and landing
|
|
6
|
+
* strategy card) so every app shows the same line, and pinned to its output
|
|
7
|
+
* for every live CMS row. The rules are facts about how the CMS is authored,
|
|
8
|
+
* not formatting preferences:
|
|
9
|
+
*
|
|
10
|
+
* - `liteDescription` IS THE SHORT ONE. `description` is the credit
|
|
11
|
+
* originator's several-paragraph profile; on a card it is a wall.
|
|
12
|
+
* - `"Not Available"` IS A PLACEHOLDER, not editorial. Several rows carry it
|
|
13
|
+
* verbatim, and it must read as missing, not print. Matched on the whole
|
|
14
|
+
* trimmed value, case-insensitively. It applies to `liteDescription` only.
|
|
15
|
+
* - EMPTY OR BLANK IS MISSING. The service maps a pool with no CMS record to
|
|
16
|
+
* `''`.
|
|
17
|
+
* - THE FIELDS HOLD MARKDOWN. `liteDescription` can open with a `**bold**`
|
|
18
|
+
* lead, and the surfaces this feeds render plain text, so the markers are
|
|
19
|
+
* stripped (bold, then italic, then inline code).
|
|
20
|
+
* - AND HARD NEWLINES. Every run of whitespace becomes one space, so a
|
|
21
|
+
* paragraph break inside the value is not a gap in a one-line slot.
|
|
22
|
+
* - NOT SANITISED. "Plain text" means text to render AS text. HTML tags,
|
|
23
|
+
* entities and link syntax (`<script>`, `<`, `[a](javascript:…)`) pass
|
|
24
|
+
* through unchanged, and removing markers can join fragments into a tag
|
|
25
|
+
* (`<scr**i**pt>` becomes `<script>`). Render it as a text node, never as
|
|
26
|
+
* HTML or markdown.
|
|
27
|
+
*
|
|
28
|
+
* Two refinements over the kasu-ui original, neither reachable by any live
|
|
29
|
+
* row: the cleaned text is trimmed (a CRLF value no longer ends in a space),
|
|
30
|
+
* and a `liteDescription` that cleans to nothing (`** **`) counts as missing,
|
|
31
|
+
* so the result is never a blank string.
|
|
32
|
+
*
|
|
33
|
+
* This authors no string of its own. It selects and cleans editorial the CMS
|
|
34
|
+
* already holds, and an absent blurb is `undefined`, never a fallback sentence:
|
|
35
|
+
* what "no blurb" means is the render site's decision.
|
|
36
|
+
*
|
|
37
|
+
* Pure. A value that is not a string reads as missing.
|
|
38
|
+
*/
|
|
39
|
+
export function pickShortDescription(
|
|
40
|
+
source: ShortDescriptionSource,
|
|
41
|
+
): string | undefined {
|
|
42
|
+
const lite = asTrimmed(source.liteDescription);
|
|
43
|
+
if (lite && !NOT_AVAILABLE.test(lite)) {
|
|
44
|
+
const summary = toOneLine(lite);
|
|
45
|
+
if (summary) return summary;
|
|
46
|
+
}
|
|
47
|
+
const long = asTrimmed(source.description);
|
|
48
|
+
if (long) {
|
|
49
|
+
const firstParagraph = long.split(PARAGRAPH_BREAK, 1)[0] ?? long;
|
|
50
|
+
return toOneLine(firstParagraph) || undefined;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The two CMS fields `pickShortDescription` reads. A `PoolOverview` and a
|
|
57
|
+
* facade `Strategy` both satisfy it.
|
|
58
|
+
*/
|
|
59
|
+
export interface ShortDescriptionSource {
|
|
60
|
+
liteDescription?: string | null;
|
|
61
|
+
description?: string | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const NOT_AVAILABLE = /^not available$/i;
|
|
65
|
+
const PARAGRAPH_BREAK = /\n\s*\n/;
|
|
66
|
+
|
|
67
|
+
function asTrimmed(value: unknown): string {
|
|
68
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Markers off, whitespace runs to one space, ends trimmed. `''` when nothing is left. */
|
|
72
|
+
function toOneLine(text: string): string {
|
|
73
|
+
return stripInlineMarkdown(text).replace(/\s+/gu, ' ').trim();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Inline markdown markers off, in the order bold → italic → code. The bold
|
|
78
|
+
* passes consume every `**` / `__` pair first, so the italic patterns can match
|
|
79
|
+
* a lone `*` / `_` without lookarounds.
|
|
80
|
+
*/
|
|
81
|
+
function stripInlineMarkdown(input: string): string {
|
|
82
|
+
return input
|
|
83
|
+
.replace(/\*\*(.+?)\*\*/g, '$1')
|
|
84
|
+
.replace(/__(.+?)__/g, '$1')
|
|
85
|
+
.replace(/\*(.+?)\*/g, '$1')
|
|
86
|
+
.replace(/_(.+?)_/g, '$1')
|
|
87
|
+
.replace(/`([^`]+)`/g, '$1');
|
|
88
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settled interest per cycle (epoch): what a lender was credited at each close,
|
|
3
|
+
* per pool and tranche, and the one formula that turns a tranche's credited
|
|
4
|
+
* interest into one lender's share of it.
|
|
5
|
+
*
|
|
6
|
+
* **The figures are NET, and only net.** `LendingPool._applyTrancheInterest`
|
|
7
|
+
* takes the performance fee off first and emits `InterestApplied` with the
|
|
8
|
+
* lender side only (`interest × (1 − performanceFee)`); a fixed-term top-up
|
|
9
|
+
* (`_applyFixedRateInterests`) is net of the fee the same way. So the figure
|
|
10
|
+
* this module computes from those records IS what the lender was credited —
|
|
11
|
+
* never take the fee off it again. No gross is offered: the subgraph keeps
|
|
12
|
+
* only TODAY's fee, so a historical gross would be a guess.
|
|
13
|
+
*
|
|
14
|
+
* Units: amounts are display units of the DEPLOYMENT'S OWN stable token (USDC
|
|
15
|
+
* on Base and XDC USDC, AUDD on XDC AUDD) — never converted to USD here;
|
|
16
|
+
* shares are display units of tranche shares, as the subgraph's BigDecimals.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** One fixed-term lock inside a tranche position, at one epoch. */
|
|
20
|
+
export interface EpochLockShares {
|
|
21
|
+
/**
|
|
22
|
+
* The lock earns in this epoch: it started BEFORE the epoch, ends at or
|
|
23
|
+
* after it, and the lender has a share snapshot for the tranche at it.
|
|
24
|
+
*/
|
|
25
|
+
active: boolean;
|
|
26
|
+
/** The lock's tranche shares as of the epoch (latest update at or before it). */
|
|
27
|
+
sharesAtEpoch: number;
|
|
28
|
+
/** The lock's tranche shares as of the epoch BEFORE it. */
|
|
29
|
+
sharesBeforeEpoch: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Everything one lender's share of one tranche's credited interest needs. */
|
|
33
|
+
export interface EpochTrancheYieldInput {
|
|
34
|
+
/** The tranche's interest credited at this epoch's close (net of the fee). */
|
|
35
|
+
epochInterest: number;
|
|
36
|
+
/** The lender's tranche shares as of the epoch (fixed-term locks included). */
|
|
37
|
+
userShares: number;
|
|
38
|
+
/** The tranche's total shares as of the epoch. */
|
|
39
|
+
trancheShares: number;
|
|
40
|
+
/**
|
|
41
|
+
* The tranche's CURRENT balance and shares: the price a fixed-term top-up
|
|
42
|
+
* (extra shares) is valued at. The subgraph keeps no per-epoch tranche
|
|
43
|
+
* balance, so an older top-up is valued at today's price — a second-order
|
|
44
|
+
* difference, because the top-up is only the fixed rate's excess over the
|
|
45
|
+
* variable one.
|
|
46
|
+
*/
|
|
47
|
+
trancheBalanceNow: number;
|
|
48
|
+
trancheSharesNow: number;
|
|
49
|
+
locks: readonly EpochLockShares[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface EpochTrancheYield {
|
|
53
|
+
/** `variable + Σ locks` — the lender's whole yield in the tranche. */
|
|
54
|
+
total: number;
|
|
55
|
+
/** The variable residual: the share-weighted base yield minus the locks' part of it. */
|
|
56
|
+
variable: number;
|
|
57
|
+
/** Each lock's yield, in the order of `input.locks`: its base part plus its top-up. */
|
|
58
|
+
locks: number[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The ONE per-epoch formula. `Portfolio.getPortfolioLendingData` runs it for
|
|
63
|
+
* the last settled epoch and `getYieldHistory` for every epoch of a window, so
|
|
64
|
+
* the two figures cannot drift apart.
|
|
65
|
+
*
|
|
66
|
+
* ```
|
|
67
|
+
* base = epochInterest × userShares / trancheShares
|
|
68
|
+
* lockBase = base × lock.sharesBeforeEpoch / userShares (active locks)
|
|
69
|
+
* topUp = (lock.sharesAtEpoch − lock.sharesBeforeEpoch) × trancheBalanceNow / trancheSharesNow
|
|
70
|
+
* variable = base − Σ lockBase
|
|
71
|
+
* total = variable + Σ (lockBase + topUp)
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* A zero denominator contributes 0 (a tranche or a lender with no shares
|
|
75
|
+
* earned nothing at that close), never `NaN`.
|
|
76
|
+
*/
|
|
77
|
+
export function epochTrancheYield(
|
|
78
|
+
input: EpochTrancheYieldInput,
|
|
79
|
+
): EpochTrancheYield {
|
|
80
|
+
const base =
|
|
81
|
+
input.trancheShares === 0
|
|
82
|
+
? 0
|
|
83
|
+
: (input.epochInterest * input.userShares) / input.trancheShares;
|
|
84
|
+
|
|
85
|
+
let variable = base;
|
|
86
|
+
const locks = input.locks.map((lock) => {
|
|
87
|
+
if (!lock.active) return 0;
|
|
88
|
+
|
|
89
|
+
const topUp =
|
|
90
|
+
input.trancheSharesNow === 0
|
|
91
|
+
? 0
|
|
92
|
+
: ((lock.sharesAtEpoch - lock.sharesBeforeEpoch) *
|
|
93
|
+
input.trancheBalanceNow) /
|
|
94
|
+
input.trancheSharesNow;
|
|
95
|
+
|
|
96
|
+
const lockBase =
|
|
97
|
+
input.userShares === 0
|
|
98
|
+
? 0
|
|
99
|
+
: (base * lock.sharesBeforeEpoch) / input.userShares;
|
|
100
|
+
|
|
101
|
+
variable -= lockBase;
|
|
102
|
+
|
|
103
|
+
return lockBase + topUp;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const total = locks.reduce((sum, lockYield) => sum + lockYield, variable);
|
|
107
|
+
|
|
108
|
+
return { total, variable, locks };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** One lender's settled yield in one tranche at one epoch. */
|
|
112
|
+
export interface YieldHistoryEntry {
|
|
113
|
+
/** The epoch (cycle) number, in the chain's numbering. */
|
|
114
|
+
epochId: number;
|
|
115
|
+
/**
|
|
116
|
+
* When the epoch ended — the next epoch's start — in unix SECONDS (not
|
|
117
|
+
* milliseconds).
|
|
118
|
+
*/
|
|
119
|
+
epochEnd: number;
|
|
120
|
+
/** Lowercased lending pool address. */
|
|
121
|
+
poolId: string;
|
|
122
|
+
/** Lowercased tranche address. */
|
|
123
|
+
trancheId: string;
|
|
124
|
+
/**
|
|
125
|
+
* What the close credited the lender in this tranche, AFTER the
|
|
126
|
+
* performance fee, in display units of the deployment's own stable token
|
|
127
|
+
* (AUDD on XDC AUDD — convert before formatting it as USD).
|
|
128
|
+
*/
|
|
129
|
+
netYield: number;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** One epoch's yield summed over the entries an aggregation kept. */
|
|
133
|
+
export interface YieldHistoryPoint {
|
|
134
|
+
/** The epoch (cycle) number. */
|
|
135
|
+
epochId: number;
|
|
136
|
+
/** The epoch's end, in unix SECONDS. */
|
|
137
|
+
epochEnd: number;
|
|
138
|
+
/** Net yield summed, in the deployment's own stable token. */
|
|
139
|
+
netYield: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface YieldHistoryFilter {
|
|
143
|
+
/** Keep only this pool (case-insensitive). */
|
|
144
|
+
poolId?: string;
|
|
145
|
+
/** Keep only this tranche (case-insensitive). */
|
|
146
|
+
trancheId?: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Pool/tranche entries → one point per epoch, ascending by `epochId`. With no
|
|
151
|
+
* filter it sums every strategy (the Lend tab's bars); with `poolId` it is one
|
|
152
|
+
* strategy (a strategy page's bars).
|
|
153
|
+
*
|
|
154
|
+
* An epoch appears only if a kept entry has it — there is no zero padding, so
|
|
155
|
+
* an empty input (a new lender) is an empty output.
|
|
156
|
+
*
|
|
157
|
+
* For a fixed-term lock holder the bars can sum to slightly MORE than the
|
|
158
|
+
* lender's lifetime interest (up to about 0.2 %): each top-up is valued at the
|
|
159
|
+
* tranche's CURRENT share price, which has grown since. Show "earned to date"
|
|
160
|
+
* from the lifetime figure, never from this sum.
|
|
161
|
+
*/
|
|
162
|
+
export function aggregateYieldHistory(
|
|
163
|
+
entries: readonly YieldHistoryEntry[],
|
|
164
|
+
filter: YieldHistoryFilter = {},
|
|
165
|
+
): YieldHistoryPoint[] {
|
|
166
|
+
const poolId = filter.poolId?.toLowerCase();
|
|
167
|
+
const trancheId = filter.trancheId?.toLowerCase();
|
|
168
|
+
const byEpoch = new Map<number, YieldHistoryPoint>();
|
|
169
|
+
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
if (poolId !== undefined && entry.poolId.toLowerCase() !== poolId) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (
|
|
175
|
+
trancheId !== undefined &&
|
|
176
|
+
entry.trancheId.toLowerCase() !== trancheId
|
|
177
|
+
) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const point = byEpoch.get(entry.epochId);
|
|
182
|
+
if (point) {
|
|
183
|
+
point.netYield += entry.netYield;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
byEpoch.set(entry.epochId, {
|
|
187
|
+
epochId: entry.epochId,
|
|
188
|
+
epochEnd: entry.epochEnd,
|
|
189
|
+
netYield: entry.netYield,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return [...byEpoch.values()].sort((a, b) => a.epochId - b.epochId);
|
|
194
|
+
}
|
package/src/facade/strategies.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { selectVisiblePools } from '../domain/pools';
|
|
2
|
+
import { pickShortDescription } from '../domain/strategy-summary';
|
|
2
3
|
import { DataService } from '../services/DataService/data-service';
|
|
3
4
|
import {
|
|
4
5
|
PoolDelegateProfileAndHistory,
|
|
@@ -218,6 +219,7 @@ export class StrategiesFacade {
|
|
|
218
219
|
subheading: nonEmptyOrUndefined(pool.subheading),
|
|
219
220
|
description: pool.description,
|
|
220
221
|
liteDescription: nonEmptyOrUndefined(pool.liteDescription),
|
|
222
|
+
summary: pickShortDescription(pool),
|
|
221
223
|
isActive: pool.isActive,
|
|
222
224
|
apy: pool.apy,
|
|
223
225
|
tvl: pool.totalValueLocked,
|
package/src/facade/types.ts
CHANGED
|
@@ -121,6 +121,19 @@ export interface Strategy {
|
|
|
121
121
|
* Absent when the record has none, or an empty one.
|
|
122
122
|
*/
|
|
123
123
|
liteDescription?: string;
|
|
124
|
+
/**
|
|
125
|
+
* The strategy's short blurb as ONE line of plain text, for cards and
|
|
126
|
+
* compact surfaces: `liteDescription` when it is usable, else the first
|
|
127
|
+
* paragraph of `description`, with inline markdown markers stripped and
|
|
128
|
+
* every run of whitespace collapsed to one space. The `"Not Available"`
|
|
129
|
+
* placeholder, an empty or blank value, and a missing one all count as
|
|
130
|
+
* absent. `undefined` when neither field yields a blurb; the SDK never
|
|
131
|
+
* substitutes a sentence of its own. See `pickShortDescription`.
|
|
132
|
+
*
|
|
133
|
+
* Not sanitised: HTML tags and link syntax pass through unchanged. Render
|
|
134
|
+
* it as text, never as HTML or markdown.
|
|
135
|
+
*/
|
|
136
|
+
summary?: string;
|
|
124
137
|
isActive: boolean;
|
|
125
138
|
/** Weighted-average APY across tranches (decimal, e.g. 0.08 = 8 %). */
|
|
126
139
|
apy: number;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Provider } from '@ethersproject/providers';
|
|
2
2
|
|
|
3
3
|
import { deriveRequestState, RequestState } from '../domain/requests';
|
|
4
|
+
import { YieldHistoryEntry } from '../domain/yield-history';
|
|
4
5
|
import { DataService } from '../services/DataService/data-service';
|
|
5
6
|
import { Portfolio } from '../services/Portfolio/portfolio';
|
|
7
|
+
import { YieldHistoryOptions } from '../services/Portfolio/yield-history';
|
|
6
8
|
import { UserRequest } from '../services/UserLending/types';
|
|
7
9
|
import { UserLending } from '../services/UserLending/user-lending';
|
|
8
10
|
|
|
@@ -39,9 +41,8 @@ export class PortfolioFacade {
|
|
|
39
41
|
): Promise<UserPositions> {
|
|
40
42
|
const currentEpoch = await this._userLending.getCurrentEpoch();
|
|
41
43
|
|
|
42
|
-
const poolOverviews =
|
|
43
|
-
currentEpoch
|
|
44
|
-
);
|
|
44
|
+
const poolOverviews =
|
|
45
|
+
await this._dataService.getPoolOverview(currentEpoch);
|
|
45
46
|
|
|
46
47
|
const pools = await this._portfolio.getPortfolioLendingData(
|
|
47
48
|
userAddress,
|
|
@@ -59,6 +60,42 @@ export class PortfolioFacade {
|
|
|
59
60
|
return { pools, summary };
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
/**
|
|
64
|
+
* The lender's settled yield per cycle, per pool and tranche: what each
|
|
65
|
+
* close credited them, NET of the performance fee (the chain credits it
|
|
66
|
+
* net), in display units of the deployment's own stable token (AUDD on
|
|
67
|
+
* XDC AUDD). `epochEnd` is unix seconds. Net only — no gross is offered.
|
|
68
|
+
*
|
|
69
|
+
* Validates `options` before any read (`RangeError` on a malformed one).
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* const entries = await kasu.portfolio.getYieldHistory('0xUser...', { count: 52 });
|
|
73
|
+
* const allStrategies = aggregateYieldHistory(entries);
|
|
74
|
+
* const oneStrategy = aggregateYieldHistory(entries, { poolId });
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* `getPositions`' `totalYieldEarningsLastEpoch` for a pool equals that
|
|
78
|
+
* pool's bar for the epoch of its most recently APPLIED interest — which
|
|
79
|
+
* is older than the last cycle for a pool that has not cleared since (the
|
|
80
|
+
* bar carries that older `epochId`). A lender who held nothing at that
|
|
81
|
+
* epoch has no bar there and a figure of 0; their newest bar is from
|
|
82
|
+
* when they last held shares.
|
|
83
|
+
*
|
|
84
|
+
* For a fixed-term lock holder the bars can sum to slightly more than the
|
|
85
|
+
* lifetime interest (up to about 0.2 %), because each top-up is valued at
|
|
86
|
+
* today's share price — show "earned to date" from the lifetime figure,
|
|
87
|
+
* never from the sum of the bars.
|
|
88
|
+
*
|
|
89
|
+
* `[]` for a lender with no history, and on a LITE deployment whose
|
|
90
|
+
* subgraph lacks the entities; on a full deployment that error throws.
|
|
91
|
+
*/
|
|
92
|
+
async getYieldHistory(
|
|
93
|
+
userAddress: string,
|
|
94
|
+
options?: YieldHistoryOptions,
|
|
95
|
+
): Promise<YieldHistoryEntry[]> {
|
|
96
|
+
return await this._portfolio.getYieldHistory(userAddress, options);
|
|
97
|
+
}
|
|
98
|
+
|
|
62
99
|
/**
|
|
63
100
|
* Fetch a user's full transaction history (deposits, withdrawals, cancellations).
|
|
64
101
|
*/
|