@kasufinance/kasu-sdk 2.14.0 → 2.15.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 +29 -5
- package/dist/bundle.cjs.js +561 -11
- package/dist/bundle.esm.js +553 -12
- package/dist/domain/index.d.ts +6 -1
- package/dist/domain/index.js +6 -2
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/loan-contract.d.ts +16 -5
- package/dist/domain/loan-contract.js +16 -5
- package/dist/domain/loan-contract.js.map +1 -1
- package/dist/domain/pool-tvl.js +179 -0
- package/dist/domain/pool-tvl.js.map +1 -1
- package/dist/domain/requests.js +29 -19
- package/dist/domain/requests.js.map +1 -1
- package/dist/domain/strategy-details.d.ts +262 -0
- package/dist/domain/strategy-details.js +375 -0
- package/dist/domain/strategy-details.js.map +1 -0
- package/dist/facade/index.d.ts +1 -1
- package/dist/facade/index.js +2 -0
- package/dist/facade/index.js.map +1 -1
- package/dist/facade/strategies.d.ts +85 -3
- package/dist/facade/strategies.js +182 -6
- package/dist/facade/strategies.js.map +1 -1
- package/dist/facade/strategy-deployments.js +97 -0
- package/dist/facade/strategy-deployments.js.map +1 -0
- package/dist/facade/types.d.ts +82 -0
- package/dist/flows/deposit-flow.d.ts +19 -5
- package/dist/flows/deposit-flow.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/services/DataService/data-service.js +80 -9
- package/dist/services/DataService/data-service.js.map +1 -1
- package/dist/services/DataService/tvl-history.js +89 -0
- package/dist/services/DataService/tvl-history.js.map +1 -1
- package/dist/services/UserLending/queries.js +2 -7
- package/dist/services/UserLending/queries.js.map +1 -1
- package/dist/services/UserLending/subgraph-types.js.map +1 -1
- package/dist/services/UserLending/types.js.map +1 -1
- package/dist/services/UserLending/user-lending.js +72 -16
- package/dist/services/UserLending/user-lending.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/index.ts +27 -1
- package/src/domain/loan-contract.ts +16 -5
- package/src/domain/strategy-details.ts +528 -0
- package/src/facade/index.ts +3 -0
- package/src/facade/strategies.ts +205 -10
- package/src/facade/types.ts +85 -0
- package/src/flows/deposit-flow.ts +19 -5
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CMS-authored figures and text a strategy's Details screen shows, read
|
|
3
|
+
* the way kasu-ui's Details tab reads them, so every app shows the same
|
|
4
|
+
* thing.
|
|
5
|
+
*
|
|
6
|
+
* Lifted from kasu-ui (`lib/details-fields.ts`, `lib/directus-text.ts` and
|
|
7
|
+
* the parsers inside `deposit-dialog/details-tab.tsx`). The rules are facts
|
|
8
|
+
* about how the CMS is authored, not presentation:
|
|
9
|
+
*
|
|
10
|
+
* - EMPTY IS UNAUTHORED. The CMS stores an emptied field as `''`, and its
|
|
11
|
+
* "numeric" fields arrive as a number, a numeric string, `''` or `null`.
|
|
12
|
+
* Anything that is not real data reads as `undefined` — never a `0`, a
|
|
13
|
+
* placeholder or a sentence of the SDK's own. A field the caller cannot
|
|
14
|
+
* read is a row the caller omits.
|
|
15
|
+
* - A START DATE MUST DATE. A value that is not an ISO date, or a real
|
|
16
|
+
* calendar date, or is before 2000 or in the future, is refused: rendered
|
|
17
|
+
* as elapsed time it would claim a history nobody authored.
|
|
18
|
+
* - SOME FIELDS CARRY TWO LINES IN ONE STRING. Business Types and Facility
|
|
19
|
+
* Type are a primary value and a qualifying clause; risk-item
|
|
20
|
+
* descriptions can be numbered enumerations. Splitting them is the same
|
|
21
|
+
* everywhere, so it lives here.
|
|
22
|
+
*
|
|
23
|
+
* Like `pickShortDescription`, this authors no string of its own: it selects,
|
|
24
|
+
* splits and trims text the CMS already holds. None of it is sanitised —
|
|
25
|
+
* render every string as text, never as HTML or markdown.
|
|
26
|
+
*
|
|
27
|
+
* Pure. No clock: the date reader takes `now` from its caller.
|
|
28
|
+
*/
|
|
29
|
+
export interface CmsStartDateOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Also accept a finite number as unix SECONDS. kasu-ui's duration
|
|
32
|
+
* formatter reads a numeric value that way, and the originator's
|
|
33
|
+
* `delegateLendingHistory` is typed as a number although the live CMS
|
|
34
|
+
* serves an ISO date. Off by default: a strategy's `operatingSince` is a
|
|
35
|
+
* date column, and kasu-ui refuses a number there.
|
|
36
|
+
*/
|
|
37
|
+
unixSeconds?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A CMS start date as its `YYYY-MM-DD` date head, or `undefined`.
|
|
41
|
+
*
|
|
42
|
+
* Accepts an ISO date, optionally with a time part (only the date head is
|
|
43
|
+
* kept — a time changes nothing at year/month granularity, and converting it
|
|
44
|
+
* through a timezone could move it a day). Refused, as `undefined`:
|
|
45
|
+
*
|
|
46
|
+
* - anything that is not a string (or, with `unixSeconds`, a number);
|
|
47
|
+
* - an empty or blank string (unauthored);
|
|
48
|
+
* - a string that is not ISO-shaped (`'Jun 2024'`);
|
|
49
|
+
* - a date that does not exist (`'2024-02-30'`, `'2024-13-01'`) — never
|
|
50
|
+
* rolled over into the next month;
|
|
51
|
+
* - a year before 2000;
|
|
52
|
+
* - a date after `now` (a typo such as 2062 for 2026 — no history has
|
|
53
|
+
* begun in the future).
|
|
54
|
+
*
|
|
55
|
+
* `now` is the caller's clock; the facade passes the current time.
|
|
56
|
+
*/
|
|
57
|
+
export declare function readCmsStartDate(value: unknown, now: Date, options?: CmsStartDateOptions): string | undefined;
|
|
58
|
+
/** A CMS value split into its primary line and an optional qualifying clause. */
|
|
59
|
+
export interface CmsTwoLineValue {
|
|
60
|
+
/** The value itself — never empty. */
|
|
61
|
+
primary: string;
|
|
62
|
+
/** The qualifying clause beneath it. Absent when none is authored. */
|
|
63
|
+
detail?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Business Types (the CMS `industryExposure`), split into the value and its
|
|
67
|
+
* supporting clause on the FIRST newline, else the FIRST parenthesised
|
|
68
|
+
* segment (a trailing `)` dropped):
|
|
69
|
+
*
|
|
70
|
+
* `'SMEs & Large Businesses (diversified industries – exclusions apply)'`
|
|
71
|
+
* → `{ primary: 'SMEs & Large Businesses', detail: 'diversified industries – exclusions apply' }`
|
|
72
|
+
*
|
|
73
|
+
* A value with neither delimiter is `{ primary }` alone. `undefined` for a
|
|
74
|
+
* missing, non-string, empty or blank value.
|
|
75
|
+
*
|
|
76
|
+
* REFINED over kasu-ui: a value that OPENS with `(` would split to an empty
|
|
77
|
+
* primary there; here the whole value is the primary instead, so `primary`
|
|
78
|
+
* is never empty. No live record has that shape.
|
|
79
|
+
*/
|
|
80
|
+
export declare function splitBusinessTypes(raw: unknown): CmsTwoLineValue | undefined;
|
|
81
|
+
/** Facility Type: the authored label, its clause, and whether it revolves. */
|
|
82
|
+
export interface StrategyFacility {
|
|
83
|
+
/** The facility's label (`'Revolving Instalment Facility'`) — never empty. */
|
|
84
|
+
label: string;
|
|
85
|
+
/** The qualifying clause beneath it. Absent when none is authored. */
|
|
86
|
+
detail?: string;
|
|
87
|
+
/**
|
|
88
|
+
* The LABEL names a revolving facility (`'Revolving'`, `'Revolving
|
|
89
|
+
* Instalment Facility'`), matched case-insensitively on a word starting
|
|
90
|
+
* `revolv`. Never true for a negated label: `'Non-Revolving Term
|
|
91
|
+
* Facility'` is false, because a hyphen before the word does not count as
|
|
92
|
+
* a word boundary here. The clause is not read, so a clause that merely
|
|
93
|
+
* mentions redraw does not make a facility revolve.
|
|
94
|
+
*
|
|
95
|
+
* kasu-ui hangs an explanatory ⓘ off a revolving label; that copy is the
|
|
96
|
+
* app's own.
|
|
97
|
+
*/
|
|
98
|
+
revolving: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Facility Type (the CMS `loanStructure`): the label on the FIRST line, and
|
|
102
|
+
* everything after the first newline as its clause, so a clause with line
|
|
103
|
+
* breaks of its own stays whole.
|
|
104
|
+
*
|
|
105
|
+
* `'Revolving Instalment Facility\n12-24 months instalment loan, subject to annual review'`
|
|
106
|
+
* → `{ label: 'Revolving Instalment Facility', detail: '12-24 months …', revolving: true }`
|
|
107
|
+
*
|
|
108
|
+
* `undefined` for a missing, non-string, empty or blank value. The value is
|
|
109
|
+
* trimmed first, so a leading blank line still yields a label.
|
|
110
|
+
*/
|
|
111
|
+
export declare function parseFacility(raw: unknown): StrategyFacility | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* The order the Risk Management groups read in, by group name (compared
|
|
114
|
+
* trimmed, case-insensitively). The CMS returns items in authoring order,
|
|
115
|
+
* which is not this. A group not listed still appears — after these, in CMS
|
|
116
|
+
* order.
|
|
117
|
+
*/
|
|
118
|
+
export declare const RISK_GROUP_ORDER: readonly string[];
|
|
119
|
+
/**
|
|
120
|
+
* A risk-item description as the lines beneath the item's name.
|
|
121
|
+
*
|
|
122
|
+
* A numbered enumeration (`'1) Foo; and, 2) Bar'`, or one that omits its
|
|
123
|
+
* leading `1)`: `'Foo; 2) Bar'`) is one line per clause; anything else is
|
|
124
|
+
* one line. Zero-width characters are stripped first. An unauthored
|
|
125
|
+
* description is NO lines (`[]`), never a dash.
|
|
126
|
+
*/
|
|
127
|
+
export declare function splitNumberedClauses(description: unknown): string[];
|
|
128
|
+
/** One risk-management item as the CMS row carries it. */
|
|
129
|
+
export interface RiskManagementItemSource {
|
|
130
|
+
name?: unknown;
|
|
131
|
+
group?: unknown;
|
|
132
|
+
description?: unknown;
|
|
133
|
+
tooltip?: unknown;
|
|
134
|
+
}
|
|
135
|
+
/** One item in a Risk Management group. */
|
|
136
|
+
export interface StrategyRiskItem {
|
|
137
|
+
/** The item's name (`'Guarantee & Indemnity'`) — never empty. */
|
|
138
|
+
name: string;
|
|
139
|
+
/**
|
|
140
|
+
* The pool's own description of it — zero-width characters stripped,
|
|
141
|
+
* trimmed. Present exactly when `clauses` is non-empty: a description
|
|
142
|
+
* that yields no line (`''`, `'—'`, zero-width characters alone) is
|
|
143
|
+
* absent.
|
|
144
|
+
*/
|
|
145
|
+
description?: string;
|
|
146
|
+
/** `description` as the lines beneath the name; `[]` when unauthored. */
|
|
147
|
+
clauses: string[];
|
|
148
|
+
/** The CMS explanation of the item (shared by every pool). Absent when unauthored. */
|
|
149
|
+
tooltip?: string;
|
|
150
|
+
}
|
|
151
|
+
/** One Risk Management group and its items, in CMS order. */
|
|
152
|
+
export interface StrategyRiskGroup {
|
|
153
|
+
/** The group's name as the CMS authors it (`'Security & Recourse'`). */
|
|
154
|
+
group: string;
|
|
155
|
+
/** Never empty. */
|
|
156
|
+
items: StrategyRiskItem[];
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Risk-management items grouped by their group, the groups in
|
|
160
|
+
* `RISK_GROUP_ORDER` and, within a group, the items in CMS order.
|
|
161
|
+
*
|
|
162
|
+
* An item with no name, or no group, is left out: there is nothing to head
|
|
163
|
+
* its lines with, or no group to place it in. (The CMS joins items to groups
|
|
164
|
+
* by name, so neither occurs in live data.) No group is ever empty, so an
|
|
165
|
+
* item list with nothing usable gives `[]`.
|
|
166
|
+
*/
|
|
167
|
+
export declare function groupRiskManagementItems(items: readonly RiskManagementItemSource[]): StrategyRiskGroup[];
|
|
168
|
+
/**
|
|
169
|
+
* The pool's security tags (the CMS `security` list), trimmed, blanks
|
|
170
|
+
* dropped. `undefined` when none remain.
|
|
171
|
+
*
|
|
172
|
+
* kasu-ui shows these under "Security Structure over End Borrowers" ONLY
|
|
173
|
+
* when the pool has no risk-management items.
|
|
174
|
+
*/
|
|
175
|
+
export declare function securityStructureOf(raw: unknown): string[] | undefined;
|
|
176
|
+
/**
|
|
177
|
+
* A CMS or subgraph "numeric" value as a finite number, or `undefined`. An
|
|
178
|
+
* empty or blank string is UNAUTHORED, not zero; a genuine `0` survives.
|
|
179
|
+
*/
|
|
180
|
+
export declare function finiteOrUndefined(value: unknown): number | undefined;
|
|
181
|
+
/** One deployment's pool of a strategy, for `strategyTotalsUsd`. */
|
|
182
|
+
export interface StrategyTotalsLeg {
|
|
183
|
+
/**
|
|
184
|
+
* Which deployment this leg is — the same key the caller lists in
|
|
185
|
+
* `expectedDeployments` (e.g. `StrategyDeployment.chain`: `'base'`,
|
|
186
|
+
* `'xdc'`). Compared exactly.
|
|
187
|
+
*/
|
|
188
|
+
deployment: string;
|
|
189
|
+
/** The pool's TVL (`Strategy.tvl.total`), in its own stable token. */
|
|
190
|
+
totalActiveLending: string | number;
|
|
191
|
+
/**
|
|
192
|
+
* The pool's lender interest earned
|
|
193
|
+
* (`Strategy.strategyHistory.lenderInterestEarned`), in its own stable
|
|
194
|
+
* token.
|
|
195
|
+
*/
|
|
196
|
+
lenderInterestEarned?: string | number;
|
|
197
|
+
/**
|
|
198
|
+
* USD per 1 unit of this deployment's stable token (`1` for USDC).
|
|
199
|
+
* `undefined` while the rate is not known.
|
|
200
|
+
*/
|
|
201
|
+
usdRate: number | undefined;
|
|
202
|
+
}
|
|
203
|
+
/** A strategy's two money figures, summed over the legs given, in USD. */
|
|
204
|
+
export interface StrategyTotalsUsd {
|
|
205
|
+
totalActiveLendingUsd: number;
|
|
206
|
+
lenderInterestEarnedUsd: number;
|
|
207
|
+
/**
|
|
208
|
+
* `true` when some expected deployment has no leg — it failed to load,
|
|
209
|
+
* or has not loaded yet — so both figures cover only `legs`, NOT the
|
|
210
|
+
* whole strategy. A caller stating them as the strategy-wide figure must
|
|
211
|
+
* say so (kasu-ui adds a partial-regions note) or fall back.
|
|
212
|
+
*/
|
|
213
|
+
isPartial: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* The expected deployments with no leg, in `expectedDeployments` order.
|
|
216
|
+
* Empty exactly when `isPartial` is `false`.
|
|
217
|
+
*/
|
|
218
|
+
missingDeployments: string[];
|
|
219
|
+
}
|
|
220
|
+
export type StrategyTotalsInputErrorCode = 'duplicate-leg' | 'unexpected-leg';
|
|
221
|
+
/**
|
|
222
|
+
* A leg `strategyTotalsUsd` cannot place: two legs for one deployment
|
|
223
|
+
* (`duplicate-leg`, which would double-count it), or a leg for a deployment
|
|
224
|
+
* not in `expectedDeployments` (`unexpected-leg`, a pool of some other
|
|
225
|
+
* strategy). Thrown, because both are caller bugs, not data states.
|
|
226
|
+
*/
|
|
227
|
+
export declare class StrategyTotalsInputError extends Error {
|
|
228
|
+
readonly code: StrategyTotalsInputErrorCode;
|
|
229
|
+
readonly deployment: string;
|
|
230
|
+
constructor(code: StrategyTotalsInputErrorCode, deployment: string);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Total Active Lending and Lender Interest Earned for a strategy across the
|
|
234
|
+
* deployments it lends on, in USD: each leg's native amount times that leg's
|
|
235
|
+
* own `usdRate`, summed. Tax Pay lends on Base (USDC) and XDC (AUDD);
|
|
236
|
+
* 2,567,901 AUDD is not US$2,567,901.
|
|
237
|
+
*
|
|
238
|
+
* `expectedDeployments` is every deployment the strategy has a pool on —
|
|
239
|
+
* `strategyDeployments(poolId, chain).map((d) => d.chain)` — and `legs` the
|
|
240
|
+
* ones whose pool the caller actually loaded. What is guaranteed:
|
|
241
|
+
*
|
|
242
|
+
* - **`null` — WITHHELD** when there are no legs, or ANY leg's rate is
|
|
243
|
+
* missing or unusable (not a finite number above 0). The total is never
|
|
244
|
+
* built on a guessed rate, and never silently drops a loaded leg; the
|
|
245
|
+
* caller shows the held pool's own figure, or nothing.
|
|
246
|
+
* - **Otherwise the sum over `legs`**, with `isPartial` /
|
|
247
|
+
* `missingDeployments` stating exactly which expected deployments it
|
|
248
|
+
* does NOT cover. `isPartial: false` is the only case in which the
|
|
249
|
+
* figures are the whole strategy.
|
|
250
|
+
* - An amount that is absent or malformed contributes nothing (a real `0`
|
|
251
|
+
* is still `0`).
|
|
252
|
+
* - Throws `StrategyTotalsInputError` for a duplicated leg or one not in
|
|
253
|
+
* `expectedDeployments`, before summing anything.
|
|
254
|
+
*
|
|
255
|
+
* Only these two figures are summed. The CMS-authored ones — every
|
|
256
|
+
* originator figure, `operatingSince`, the loss rates — are shared by a
|
|
257
|
+
* strategy's pools and already strategy-wide: summing them double-counts.
|
|
258
|
+
*
|
|
259
|
+
* Mirrors the money half of kasu-ui's `aggregateStrategyPools` and its
|
|
260
|
+
* withhold gate.
|
|
261
|
+
*/
|
|
262
|
+
export declare function strategyTotalsUsd(legs: readonly StrategyTotalsLeg[], expectedDeployments: readonly string[]): StrategyTotalsUsd | null;
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CMS-authored figures and text a strategy's Details screen shows, read
|
|
3
|
+
* the way kasu-ui's Details tab reads them, so every app shows the same
|
|
4
|
+
* thing.
|
|
5
|
+
*
|
|
6
|
+
* Lifted from kasu-ui (`lib/details-fields.ts`, `lib/directus-text.ts` and
|
|
7
|
+
* the parsers inside `deposit-dialog/details-tab.tsx`). The rules are facts
|
|
8
|
+
* about how the CMS is authored, not presentation:
|
|
9
|
+
*
|
|
10
|
+
* - EMPTY IS UNAUTHORED. The CMS stores an emptied field as `''`, and its
|
|
11
|
+
* "numeric" fields arrive as a number, a numeric string, `''` or `null`.
|
|
12
|
+
* Anything that is not real data reads as `undefined` — never a `0`, a
|
|
13
|
+
* placeholder or a sentence of the SDK's own. A field the caller cannot
|
|
14
|
+
* read is a row the caller omits.
|
|
15
|
+
* - A START DATE MUST DATE. A value that is not an ISO date, or a real
|
|
16
|
+
* calendar date, or is before 2000 or in the future, is refused: rendered
|
|
17
|
+
* as elapsed time it would claim a history nobody authored.
|
|
18
|
+
* - SOME FIELDS CARRY TWO LINES IN ONE STRING. Business Types and Facility
|
|
19
|
+
* Type are a primary value and a qualifying clause; risk-item
|
|
20
|
+
* descriptions can be numbered enumerations. Splitting them is the same
|
|
21
|
+
* everywhere, so it lives here.
|
|
22
|
+
*
|
|
23
|
+
* Like `pickShortDescription`, this authors no string of its own: it selects,
|
|
24
|
+
* splits and trims text the CMS already holds. None of it is sanitised —
|
|
25
|
+
* render every string as text, never as HTML or markdown.
|
|
26
|
+
*
|
|
27
|
+
* Pure. No clock: the date reader takes `now` from its caller.
|
|
28
|
+
*/
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Start dates
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* `YYYY-MM-DD`, optionally followed by a time part — the two shapes a CMS
|
|
34
|
+
* date column serialises to. Checked BEFORE any parse: `new Date('Jun 2024')`
|
|
35
|
+
* is a valid date in V8, so an editorial string would otherwise become a
|
|
36
|
+
* confident duration.
|
|
37
|
+
*/
|
|
38
|
+
const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})(?:[T ].*)?$/;
|
|
39
|
+
/** Nothing on Kasu has a lending history from before this year. */
|
|
40
|
+
const EARLIEST_YEAR = 2000;
|
|
41
|
+
/**
|
|
42
|
+
* A CMS start date as its `YYYY-MM-DD` date head, or `undefined`.
|
|
43
|
+
*
|
|
44
|
+
* Accepts an ISO date, optionally with a time part (only the date head is
|
|
45
|
+
* kept — a time changes nothing at year/month granularity, and converting it
|
|
46
|
+
* through a timezone could move it a day). Refused, as `undefined`:
|
|
47
|
+
*
|
|
48
|
+
* - anything that is not a string (or, with `unixSeconds`, a number);
|
|
49
|
+
* - an empty or blank string (unauthored);
|
|
50
|
+
* - a string that is not ISO-shaped (`'Jun 2024'`);
|
|
51
|
+
* - a date that does not exist (`'2024-02-30'`, `'2024-13-01'`) — never
|
|
52
|
+
* rolled over into the next month;
|
|
53
|
+
* - a year before 2000;
|
|
54
|
+
* - a date after `now` (a typo such as 2062 for 2026 — no history has
|
|
55
|
+
* begun in the future).
|
|
56
|
+
*
|
|
57
|
+
* `now` is the caller's clock; the facade passes the current time.
|
|
58
|
+
*/
|
|
59
|
+
export function readCmsStartDate(value, now, options = {}) {
|
|
60
|
+
let head;
|
|
61
|
+
if (typeof value === 'number' && options.unixSeconds) {
|
|
62
|
+
// `0` is formatDuration's "unset" sentinel; negatives are pre-1970.
|
|
63
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
64
|
+
return undefined;
|
|
65
|
+
const date = new Date(value * 1000);
|
|
66
|
+
if (Number.isNaN(date.getTime()))
|
|
67
|
+
return undefined;
|
|
68
|
+
head = date.toISOString().slice(0, 10);
|
|
69
|
+
}
|
|
70
|
+
else if (typeof value === 'string') {
|
|
71
|
+
const trimmed = value.trim();
|
|
72
|
+
if (!ISO_DATE.test(trimmed))
|
|
73
|
+
return undefined;
|
|
74
|
+
head = trimmed.slice(0, 10);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const match = ISO_DATE.exec(head);
|
|
80
|
+
if (!match)
|
|
81
|
+
return undefined;
|
|
82
|
+
const year = Number(match[1]);
|
|
83
|
+
const month = Number(match[2]);
|
|
84
|
+
const day = Number(match[3]);
|
|
85
|
+
// Round-trip through UTC: a day or month out of range comes back as a
|
|
86
|
+
// different date, which is how a non-existent date is caught.
|
|
87
|
+
const utc = new Date(Date.UTC(year, month - 1, day));
|
|
88
|
+
if (utc.getUTCFullYear() !== year ||
|
|
89
|
+
utc.getUTCMonth() !== month - 1 ||
|
|
90
|
+
utc.getUTCDate() !== day) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
if (year < EARLIEST_YEAR)
|
|
94
|
+
return undefined;
|
|
95
|
+
if (utc.getTime() > now.getTime())
|
|
96
|
+
return undefined;
|
|
97
|
+
return head;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Business Types (the CMS `industryExposure`), split into the value and its
|
|
101
|
+
* supporting clause on the FIRST newline, else the FIRST parenthesised
|
|
102
|
+
* segment (a trailing `)` dropped):
|
|
103
|
+
*
|
|
104
|
+
* `'SMEs & Large Businesses (diversified industries – exclusions apply)'`
|
|
105
|
+
* → `{ primary: 'SMEs & Large Businesses', detail: 'diversified industries – exclusions apply' }`
|
|
106
|
+
*
|
|
107
|
+
* A value with neither delimiter is `{ primary }` alone. `undefined` for a
|
|
108
|
+
* missing, non-string, empty or blank value.
|
|
109
|
+
*
|
|
110
|
+
* REFINED over kasu-ui: a value that OPENS with `(` would split to an empty
|
|
111
|
+
* primary there; here the whole value is the primary instead, so `primary`
|
|
112
|
+
* is never empty. No live record has that shape.
|
|
113
|
+
*/
|
|
114
|
+
export function splitBusinessTypes(raw) {
|
|
115
|
+
const value = typeof raw === 'string' ? raw.trim() : '';
|
|
116
|
+
if (!value)
|
|
117
|
+
return undefined;
|
|
118
|
+
let primary = value;
|
|
119
|
+
let detail = '';
|
|
120
|
+
const newlineAt = value.indexOf('\n');
|
|
121
|
+
if (newlineAt !== -1) {
|
|
122
|
+
primary = value.slice(0, newlineAt).trim();
|
|
123
|
+
detail = value.slice(newlineAt + 1).trim();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const parenAt = value.indexOf('(');
|
|
127
|
+
if (parenAt !== -1) {
|
|
128
|
+
primary = value.slice(0, parenAt).trim();
|
|
129
|
+
detail = value.slice(parenAt + 1).trim();
|
|
130
|
+
if (detail.endsWith(')'))
|
|
131
|
+
detail = detail.slice(0, -1).trim();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!primary)
|
|
135
|
+
return { primary: value };
|
|
136
|
+
return detail ? { primary, detail } : { primary };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The start of the label, or a character that is neither a word character
|
|
140
|
+
* nor a hyphen, before `revolv` — not `\b`, which treats a hyphen as a
|
|
141
|
+
* boundary, so "Non-Revolving" would match. kasu-ui writes the same rule as
|
|
142
|
+
* the lookbehind `(?<![\w-])`; this form needs no lookbehind support from the
|
|
143
|
+
* JavaScript engine.
|
|
144
|
+
*/
|
|
145
|
+
const REVOLVING_FACILITY = /(?:^|[^\w-])revolv\w*\b/i;
|
|
146
|
+
/**
|
|
147
|
+
* Facility Type (the CMS `loanStructure`): the label on the FIRST line, and
|
|
148
|
+
* everything after the first newline as its clause, so a clause with line
|
|
149
|
+
* breaks of its own stays whole.
|
|
150
|
+
*
|
|
151
|
+
* `'Revolving Instalment Facility\n12-24 months instalment loan, subject to annual review'`
|
|
152
|
+
* → `{ label: 'Revolving Instalment Facility', detail: '12-24 months …', revolving: true }`
|
|
153
|
+
*
|
|
154
|
+
* `undefined` for a missing, non-string, empty or blank value. The value is
|
|
155
|
+
* trimmed first, so a leading blank line still yields a label.
|
|
156
|
+
*/
|
|
157
|
+
export function parseFacility(raw) {
|
|
158
|
+
const value = typeof raw === 'string' ? raw.trim() : '';
|
|
159
|
+
if (!value)
|
|
160
|
+
return undefined;
|
|
161
|
+
const breakAt = value.indexOf('\n');
|
|
162
|
+
const label = (breakAt === -1 ? value : value.slice(0, breakAt)).trim();
|
|
163
|
+
const detail = breakAt === -1 ? '' : value.slice(breakAt + 1).trim();
|
|
164
|
+
const revolving = REVOLVING_FACILITY.test(label);
|
|
165
|
+
return detail ? { label, detail, revolving } : { label, revolving };
|
|
166
|
+
}
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Risk Management
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
/**
|
|
171
|
+
* The order the Risk Management groups read in, by group name (compared
|
|
172
|
+
* trimmed, case-insensitively). The CMS returns items in authoring order,
|
|
173
|
+
* which is not this. A group not listed still appears — after these, in CMS
|
|
174
|
+
* order.
|
|
175
|
+
*/
|
|
176
|
+
export const RISK_GROUP_ORDER = Object.freeze([
|
|
177
|
+
'Security & Recourse',
|
|
178
|
+
'Structural Controls',
|
|
179
|
+
'Financial Covenants',
|
|
180
|
+
'Reporting Covenants',
|
|
181
|
+
'Key Eligibility Criteria',
|
|
182
|
+
]);
|
|
183
|
+
/** Zero-width paste artifacts, which `\s` does not match. */
|
|
184
|
+
const ZERO_WIDTH = /[-]/g;
|
|
185
|
+
/** An `N)` marker at the start, or after a `;` / `; and,` separator. */
|
|
186
|
+
const HAS_ENUMERATION = /(?:^\d+\)|;\s*(?:and,?\s*)?\d+\))/;
|
|
187
|
+
const ENUMERATION_SPLIT = /(?:^|\s*;\s*(?:and,?\s*)?)\d+\)\s*/;
|
|
188
|
+
/** kasu-ui's stub for an unauthored description; never a clause. */
|
|
189
|
+
const EMPTY_DESCRIPTION = '—';
|
|
190
|
+
/**
|
|
191
|
+
* A risk-item description as the lines beneath the item's name.
|
|
192
|
+
*
|
|
193
|
+
* A numbered enumeration (`'1) Foo; and, 2) Bar'`, or one that omits its
|
|
194
|
+
* leading `1)`: `'Foo; 2) Bar'`) is one line per clause; anything else is
|
|
195
|
+
* one line. Zero-width characters are stripped first. An unauthored
|
|
196
|
+
* description is NO lines (`[]`), never a dash.
|
|
197
|
+
*/
|
|
198
|
+
export function splitNumberedClauses(description) {
|
|
199
|
+
const raw = cleanDescription(description);
|
|
200
|
+
if (!raw)
|
|
201
|
+
return [];
|
|
202
|
+
const clauses = HAS_ENUMERATION.test(raw)
|
|
203
|
+
? raw
|
|
204
|
+
.split(ENUMERATION_SPLIT)
|
|
205
|
+
.map((part) => part.trim())
|
|
206
|
+
.filter((part) => part.length > 0)
|
|
207
|
+
: [raw];
|
|
208
|
+
const lines = clauses.length > 0 ? clauses : [raw];
|
|
209
|
+
return lines.filter((line) => line !== EMPTY_DESCRIPTION);
|
|
210
|
+
}
|
|
211
|
+
/** A description with zero-width characters stripped, trimmed; `''` when not a string. */
|
|
212
|
+
function cleanDescription(description) {
|
|
213
|
+
return typeof description === 'string'
|
|
214
|
+
? description.replace(ZERO_WIDTH, '').trim()
|
|
215
|
+
: '';
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Risk-management items grouped by their group, the groups in
|
|
219
|
+
* `RISK_GROUP_ORDER` and, within a group, the items in CMS order.
|
|
220
|
+
*
|
|
221
|
+
* An item with no name, or no group, is left out: there is nothing to head
|
|
222
|
+
* its lines with, or no group to place it in. (The CMS joins items to groups
|
|
223
|
+
* by name, so neither occurs in live data.) No group is ever empty, so an
|
|
224
|
+
* item list with nothing usable gives `[]`.
|
|
225
|
+
*/
|
|
226
|
+
export function groupRiskManagementItems(items) {
|
|
227
|
+
const groups = new Map();
|
|
228
|
+
for (const source of items) {
|
|
229
|
+
const name = trimmedOrUndefined(source.name);
|
|
230
|
+
const group = trimmedOrUndefined(source.group);
|
|
231
|
+
if (!name || !group)
|
|
232
|
+
continue;
|
|
233
|
+
const clauses = splitNumberedClauses(source.description);
|
|
234
|
+
// The same cleaned text the clauses come from, and only when they
|
|
235
|
+
// say something: a description of "—" or of zero-width characters
|
|
236
|
+
// alone is unauthored, so it is absent here too, never a stray dash.
|
|
237
|
+
const description = clauses.length > 0 ? cleanDescription(source.description) : '';
|
|
238
|
+
const tooltip = trimmedOrUndefined(source.tooltip);
|
|
239
|
+
const item = Object.assign(Object.assign(Object.assign({ name }, (description ? { description } : {})), { clauses }), (tooltip ? { tooltip } : {}));
|
|
240
|
+
const existing = groups.get(group);
|
|
241
|
+
if (existing)
|
|
242
|
+
existing.items.push(item);
|
|
243
|
+
else
|
|
244
|
+
groups.set(group, { group, items: [item] });
|
|
245
|
+
}
|
|
246
|
+
// Array.prototype.sort is stable, so unlisted groups keep CMS order.
|
|
247
|
+
return [...groups.values()].sort((a, b) => riskGroupRank(a.group) - riskGroupRank(b.group));
|
|
248
|
+
}
|
|
249
|
+
const RISK_GROUP_RANK = new Map(RISK_GROUP_ORDER.map((group, index) => [group.toLowerCase(), index]));
|
|
250
|
+
function riskGroupRank(group) {
|
|
251
|
+
var _a;
|
|
252
|
+
return ((_a = RISK_GROUP_RANK.get(group.trim().toLowerCase())) !== null && _a !== void 0 ? _a : RISK_GROUP_ORDER.length);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The pool's security tags (the CMS `security` list), trimmed, blanks
|
|
256
|
+
* dropped. `undefined` when none remain.
|
|
257
|
+
*
|
|
258
|
+
* kasu-ui shows these under "Security Structure over End Borrowers" ONLY
|
|
259
|
+
* when the pool has no risk-management items.
|
|
260
|
+
*/
|
|
261
|
+
export function securityStructureOf(raw) {
|
|
262
|
+
if (!Array.isArray(raw))
|
|
263
|
+
return undefined;
|
|
264
|
+
const tags = raw
|
|
265
|
+
.map((tag) => trimmedOrUndefined(tag))
|
|
266
|
+
.filter((tag) => tag !== undefined);
|
|
267
|
+
return tags.length > 0 ? tags : undefined;
|
|
268
|
+
}
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
// Numbers
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
/**
|
|
273
|
+
* A CMS or subgraph "numeric" value as a finite number, or `undefined`. An
|
|
274
|
+
* empty or blank string is UNAUTHORED, not zero; a genuine `0` survives.
|
|
275
|
+
*/
|
|
276
|
+
export function finiteOrUndefined(value) {
|
|
277
|
+
if (typeof value === 'number') {
|
|
278
|
+
return Number.isFinite(value) ? value : undefined;
|
|
279
|
+
}
|
|
280
|
+
if (typeof value === 'string') {
|
|
281
|
+
if (value.trim() === '')
|
|
282
|
+
return undefined;
|
|
283
|
+
const numeric = Number(value);
|
|
284
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* A leg `strategyTotalsUsd` cannot place: two legs for one deployment
|
|
290
|
+
* (`duplicate-leg`, which would double-count it), or a leg for a deployment
|
|
291
|
+
* not in `expectedDeployments` (`unexpected-leg`, a pool of some other
|
|
292
|
+
* strategy). Thrown, because both are caller bugs, not data states.
|
|
293
|
+
*/
|
|
294
|
+
export class StrategyTotalsInputError extends Error {
|
|
295
|
+
constructor(code, deployment) {
|
|
296
|
+
super(code === 'duplicate-leg'
|
|
297
|
+
? `strategyTotalsUsd: two legs for deployment "${deployment}"`
|
|
298
|
+
: `strategyTotalsUsd: leg for deployment "${deployment}" is not in expectedDeployments`);
|
|
299
|
+
this.code = code;
|
|
300
|
+
this.deployment = deployment;
|
|
301
|
+
this.name = 'StrategyTotalsInputError';
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Total Active Lending and Lender Interest Earned for a strategy across the
|
|
306
|
+
* deployments it lends on, in USD: each leg's native amount times that leg's
|
|
307
|
+
* own `usdRate`, summed. Tax Pay lends on Base (USDC) and XDC (AUDD);
|
|
308
|
+
* 2,567,901 AUDD is not US$2,567,901.
|
|
309
|
+
*
|
|
310
|
+
* `expectedDeployments` is every deployment the strategy has a pool on —
|
|
311
|
+
* `strategyDeployments(poolId, chain).map((d) => d.chain)` — and `legs` the
|
|
312
|
+
* ones whose pool the caller actually loaded. What is guaranteed:
|
|
313
|
+
*
|
|
314
|
+
* - **`null` — WITHHELD** when there are no legs, or ANY leg's rate is
|
|
315
|
+
* missing or unusable (not a finite number above 0). The total is never
|
|
316
|
+
* built on a guessed rate, and never silently drops a loaded leg; the
|
|
317
|
+
* caller shows the held pool's own figure, or nothing.
|
|
318
|
+
* - **Otherwise the sum over `legs`**, with `isPartial` /
|
|
319
|
+
* `missingDeployments` stating exactly which expected deployments it
|
|
320
|
+
* does NOT cover. `isPartial: false` is the only case in which the
|
|
321
|
+
* figures are the whole strategy.
|
|
322
|
+
* - An amount that is absent or malformed contributes nothing (a real `0`
|
|
323
|
+
* is still `0`).
|
|
324
|
+
* - Throws `StrategyTotalsInputError` for a duplicated leg or one not in
|
|
325
|
+
* `expectedDeployments`, before summing anything.
|
|
326
|
+
*
|
|
327
|
+
* Only these two figures are summed. The CMS-authored ones — every
|
|
328
|
+
* originator figure, `operatingSince`, the loss rates — are shared by a
|
|
329
|
+
* strategy's pools and already strategy-wide: summing them double-counts.
|
|
330
|
+
*
|
|
331
|
+
* Mirrors the money half of kasu-ui's `aggregateStrategyPools` and its
|
|
332
|
+
* withhold gate.
|
|
333
|
+
*/
|
|
334
|
+
export function strategyTotalsUsd(legs, expectedDeployments) {
|
|
335
|
+
var _a, _b;
|
|
336
|
+
const expected = new Set(expectedDeployments);
|
|
337
|
+
const seen = new Set();
|
|
338
|
+
for (const leg of legs) {
|
|
339
|
+
if (seen.has(leg.deployment)) {
|
|
340
|
+
throw new StrategyTotalsInputError('duplicate-leg', leg.deployment);
|
|
341
|
+
}
|
|
342
|
+
if (!expected.has(leg.deployment)) {
|
|
343
|
+
throw new StrategyTotalsInputError('unexpected-leg', leg.deployment);
|
|
344
|
+
}
|
|
345
|
+
seen.add(leg.deployment);
|
|
346
|
+
}
|
|
347
|
+
if (legs.length === 0)
|
|
348
|
+
return null;
|
|
349
|
+
let totalActiveLendingUsd = 0;
|
|
350
|
+
let lenderInterestEarnedUsd = 0;
|
|
351
|
+
for (const leg of legs) {
|
|
352
|
+
const rate = leg.usdRate;
|
|
353
|
+
if (typeof rate !== 'number' || !Number.isFinite(rate) || rate <= 0) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
totalActiveLendingUsd +=
|
|
357
|
+
((_a = finiteOrUndefined(leg.totalActiveLending)) !== null && _a !== void 0 ? _a : 0) * rate;
|
|
358
|
+
lenderInterestEarnedUsd +=
|
|
359
|
+
((_b = finiteOrUndefined(leg.lenderInterestEarned)) !== null && _b !== void 0 ? _b : 0) * rate;
|
|
360
|
+
}
|
|
361
|
+
const missingDeployments = [...expected].filter((d) => !seen.has(d));
|
|
362
|
+
return {
|
|
363
|
+
totalActiveLendingUsd,
|
|
364
|
+
lenderInterestEarnedUsd,
|
|
365
|
+
isPartial: missingDeployments.length > 0,
|
|
366
|
+
missingDeployments,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function trimmedOrUndefined(value) {
|
|
370
|
+
if (typeof value !== 'string')
|
|
371
|
+
return undefined;
|
|
372
|
+
const trimmed = value.trim();
|
|
373
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=strategy-details.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-details.js","sourceRoot":"","sources":["../../src/domain/strategy-details.ts"],"names":[],"mappings":"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"}
|
package/dist/facade/index.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ export { CHAIN_CONFIGS } from './chain-configs';
|
|
|
11
11
|
export { StrategyDeploymentInputError, strategyDeployments, } from './strategy-deployments';
|
|
12
12
|
export type { StrategyDeployment, StrategyDeploymentInputErrorCode, } from './strategy-deployments';
|
|
13
13
|
export { fetchUnusedPoolIds } from './unused-pool-ids';
|
|
14
|
-
export type { SupportedChain, ChainConfigEntry, StableAsset, KasuOptions, Strategy, StrategyTranche, FixedTermOption, DepositParams, WithdrawParams, DepositLimits, KycParams, UserPositions, PlatformStats, StrategyRiskPerformance, } from './types';
|
|
14
|
+
export type { SupportedChain, ChainConfigEntry, StableAsset, KasuOptions, Strategy, StrategyTranche, FixedTermOption, DepositParams, WithdrawParams, DepositLimits, KycParams, UserPositions, PlatformStats, StrategyRiskPerformance, StrategyHistory, StrategyEndBorrowers, OriginatorHistory, } from './types';
|
package/dist/facade/index.js
CHANGED
|
@@ -10,6 +10,8 @@ export { CallsFacade } from './calls';
|
|
|
10
10
|
export { READ_ONLY_MESSAGE } from './read-only';
|
|
11
11
|
// Chain configurations
|
|
12
12
|
export { CHAIN_CONFIGS } from './chain-configs';
|
|
13
|
+
// Strategy ↔ deployment resolution (pure, over CHAIN_CONFIGS)
|
|
14
|
+
export { StrategyDeploymentInputError, strategyDeployments, } from './strategy-deployments';
|
|
13
15
|
// Directus-backed helpers (I/O — not part of `domain/`)
|
|
14
16
|
export { fetchUnusedPoolIds } from './unused-pool-ids';
|
|
15
17
|
//# sourceMappingURL=index.js.map
|