@kasufinance/kasu-sdk 2.13.1 → 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.
Files changed (56) hide show
  1. package/README.md +68 -5
  2. package/dist/bundle.cjs.js +1038 -29
  3. package/dist/bundle.esm.js +1026 -30
  4. package/dist/domain/index.d.ts +8 -3
  5. package/dist/domain/index.js +6 -2
  6. package/dist/domain/index.js.map +1 -1
  7. package/dist/domain/loan-contract.d.ts +16 -5
  8. package/dist/domain/loan-contract.js +16 -5
  9. package/dist/domain/loan-contract.js.map +1 -1
  10. package/dist/domain/pool-tvl.d.ts +104 -0
  11. package/dist/domain/pool-tvl.js +179 -0
  12. package/dist/domain/pool-tvl.js.map +1 -1
  13. package/dist/domain/requests.js +29 -19
  14. package/dist/domain/requests.js.map +1 -1
  15. package/dist/domain/strategy-details.d.ts +262 -0
  16. package/dist/domain/strategy-details.js +375 -0
  17. package/dist/domain/strategy-details.js.map +1 -0
  18. package/dist/facade/index.d.ts +3 -1
  19. package/dist/facade/index.js +2 -0
  20. package/dist/facade/index.js.map +1 -1
  21. package/dist/facade/strategies.d.ts +102 -4
  22. package/dist/facade/strategies.js +182 -6
  23. package/dist/facade/strategies.js.map +1 -1
  24. package/dist/facade/strategy-deployments.d.ts +65 -0
  25. package/dist/facade/strategy-deployments.js +97 -0
  26. package/dist/facade/strategy-deployments.js.map +1 -0
  27. package/dist/facade/types.d.ts +82 -0
  28. package/dist/flows/deposit-flow.d.ts +19 -5
  29. package/dist/flows/deposit-flow.js.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/services/DataService/data-service.d.ts +29 -1
  33. package/dist/services/DataService/data-service.js +80 -9
  34. package/dist/services/DataService/data-service.js.map +1 -1
  35. package/dist/services/DataService/tvl-history.d.ts +49 -0
  36. package/dist/services/DataService/tvl-history.js +89 -0
  37. package/dist/services/DataService/tvl-history.js.map +1 -1
  38. package/dist/services/UserLending/queries.js +2 -7
  39. package/dist/services/UserLending/queries.js.map +1 -1
  40. package/dist/services/UserLending/subgraph-types.js.map +1 -1
  41. package/dist/services/UserLending/types.js.map +1 -1
  42. package/dist/services/UserLending/user-lending.js +72 -16
  43. package/dist/services/UserLending/user-lending.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/domain/index.ts +34 -3
  46. package/src/domain/loan-contract.ts +16 -5
  47. package/src/domain/pool-tvl.ts +281 -0
  48. package/src/domain/strategy-details.ts +528 -0
  49. package/src/facade/index.ts +13 -0
  50. package/src/facade/strategies.ts +231 -11
  51. package/src/facade/strategy-deployments.ts +161 -0
  52. package/src/facade/types.ts +85 -0
  53. package/src/flows/deposit-flow.ts +19 -5
  54. package/src/index.ts +4 -1
  55. package/src/services/DataService/data-service.ts +103 -7
  56. package/src/services/DataService/tvl-history.ts +131 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/facade/index.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,gDAAgD;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAOtC,0CAA0C;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,uBAAuB;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,wDAAwD;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/facade/index.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,gDAAgD;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAOtC,0CAA0C;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,uBAAuB;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,8DAA8D;AAC9D,OAAO,EACH,4BAA4B,EAC5B,mBAAmB,GACtB,MAAM,wBAAwB,CAAC;AAMhC,wDAAwD;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,9 +1,10 @@
1
1
  import { PoolTvlHistoryEntry } from '../domain/pool-tvl';
2
+ import { StrategyRiskGroup } from '../domain/strategy-details';
2
3
  import { DataService } from '../services/DataService/data-service';
3
- import { PoolTvlHistoryOptions } from '../services/DataService/tvl-history';
4
+ import { PoolTvlHistoryOptions, PoolTvlHistoryResult } from '../services/DataService/tvl-history';
4
5
  import { PoolDelegateProfileAndHistory } from '../services/DataService/types';
5
6
  import { UserLending } from '../services/UserLending/user-lending';
6
- import { DepositLimits, PlatformStats, Strategy, StrategyRiskPerformance, StrategyTranche } from './types';
7
+ import { DepositLimits, OriginatorHistory, PlatformStats, Strategy, StrategyRiskPerformance, StrategyTranche } from './types';
7
8
  /**
8
9
  * High-level facade for browsing Kasu lending strategies (pools).
9
10
  *
@@ -17,12 +18,48 @@ export declare class StrategiesFacade {
17
18
  * share their Base counterpart's editorial record). Lowercase keys.
18
19
  */
19
20
  private _poolMetadataMapping;
21
+ /**
22
+ * The clock the CMS start dates are checked against (a date after it
23
+ * is refused). Injected for tests; the current time otherwise.
24
+ */
25
+ private _now;
26
+ /**
27
+ * Milliseconds on a clock that only moves forward, for the shared
28
+ * CMS reads' 30-second lifetime — separate from `_now`, so a pinned
29
+ * date clock cannot keep a read alive for ever. Injected for tests;
30
+ * `Date.now` otherwise.
31
+ */
32
+ private _memoClockMs;
20
33
  constructor(_dataService: DataService, _userLending: UserLending,
21
34
  /**
22
35
  * Chain pool id → the pool id its CMS record is keyed by (XDC pools
23
36
  * share their Base counterpart's editorial record). Lowercase keys.
24
37
  */
25
- _poolMetadataMapping?: Record<string, string>);
38
+ _poolMetadataMapping?: Record<string, string>,
39
+ /**
40
+ * The clock the CMS start dates are checked against (a date after it
41
+ * is refused). Injected for tests; the current time otherwise.
42
+ */
43
+ _now?: () => Date,
44
+ /**
45
+ * Milliseconds on a clock that only moves forward, for the shared
46
+ * CMS reads' 30-second lifetime — separate from `_now`, so a pinned
47
+ * date clock cannot keep a read alive for ever. Injected for tests;
48
+ * `Date.now` otherwise.
49
+ */
50
+ _memoClockMs?: () => number);
51
+ /**
52
+ * Short-lived, per-instance memo of the two CMS-wide reads the pool
53
+ * getters share, so a Details screen asking for the loss rate, the risk
54
+ * groups and the originator together reads each collection once. Keyed
55
+ * by read; holds the in-flight promise, so concurrent callers share it.
56
+ * A REJECTED read is dropped at once, never served again — the next call
57
+ * retries.
58
+ */
59
+ private _cmsReads;
60
+ private _memoCmsRead;
61
+ private _riskManagementRecords;
62
+ private _originatorProfiles;
26
63
  /**
27
64
  * The pool's loss rate and first-loss capital, from its CMS
28
65
  * risk-management record. `null` when the pool has no record.
@@ -34,7 +71,9 @@ export declare class StrategiesFacade {
34
71
  * 0..1 fraction.
35
72
  *
36
73
  * Requires `directusUrl`; without it the call rejects with
37
- * `NO_DIRECTUS_URL_MESSAGE`, like every CMS-only read.
74
+ * `NO_DIRECTUS_URL_MESSAGE`, like every CMS-only read. Shares its CMS
75
+ * read with `getRiskManagementGroups` for 30 seconds per instance; a
76
+ * failed read is never reused.
38
77
  */
39
78
  getRiskPerformance(poolId: string): Promise<StrategyRiskPerformance | null>;
40
79
  /**
@@ -50,8 +89,51 @@ export declare class StrategiesFacade {
50
89
  * deployment every profile lists no pools and this resolves `null` —
51
90
  * the same answer kasu-ui's own lookup gives there today. The metadata
52
91
  * candidate becomes live once the service resolves the mapping.
92
+ *
93
+ * Shares its reads with `getOriginatorHistory` for 30 seconds per
94
+ * instance; a failed read is never reused. Each call returns its own
95
+ * copy of the profile, so mutating it changes nothing shared.
53
96
  */
54
97
  getOriginator(poolId: string): Promise<PoolDelegateProfileAndHistory | null>;
98
+ /**
99
+ * The credit originator's ENTIRE lending history for a pool — since when,
100
+ * total originated, loans outstanding, loss rate — read from the profile
101
+ * `getOriginator` finds, each figure validated. `null` when no profile
102
+ * lists the pool, or the profile authors none of the four.
103
+ *
104
+ * kasu-ui's Details tab shows these as its Credit Originator strip, and
105
+ * hides the strip when there is no profile. The money figures are
106
+ * editorial USD on every deployment: never FX-convert them. An XDC pool
107
+ * resolves `null` today, as it does in kasu-ui (see `getOriginator`).
108
+ *
109
+ * Requires `directusUrl`, like every CMS-only read; rejects when the
110
+ * read fails. Shares its reads with `getOriginator` for 30 seconds per
111
+ * instance; a failed read is never reused.
112
+ */
113
+ getOriginatorHistory(poolId: string): Promise<OriginatorHistory | null>;
114
+ /**
115
+ * The pool's Risk Management groups, from its CMS risk-management record:
116
+ * each group with its items (name, the pool's description of it split
117
+ * into lines, the shared tooltip), the groups in `RISK_GROUP_ORDER`
118
+ * (Security & Recourse, Structural Controls, Financial Covenants,
119
+ * Reporting Covenants, Key Eligibility Criteria, then any other in CMS
120
+ * order). See `groupRiskManagementItems`.
121
+ *
122
+ * `null` when the pool has no record, or the record has no usable item —
123
+ * then kasu-ui falls back to `Strategy.securityStructure`. XDC pools
124
+ * resolve through the metadata mapping to their Base record, like
125
+ * `getRiskPerformance`.
126
+ *
127
+ * REJECTS when the CMS read fails (an outage, or no `directusUrl` —
128
+ * `NO_DIRECTUS_URL_MESSAGE`), so a failure stays visible rather than
129
+ * reading as "no items". For what to SHOW, treat a rejection like `null`:
130
+ * fall back to `Strategy.securityStructure`, which arrives with the
131
+ * strategy and needs no second read.
132
+ *
133
+ * Shares its CMS read with `getRiskPerformance` for 30 seconds per
134
+ * instance; a failed read is never reused.
135
+ */
136
+ getRiskManagementGroups(poolId: string): Promise<StrategyRiskGroup[] | null>;
55
137
  private _metadataIdOf;
56
138
  /**
57
139
  * Fetch all active lending strategies.
@@ -104,6 +186,22 @@ export declare class StrategiesFacade {
104
186
  * ```
105
187
  */
106
188
  getPoolTvlHistory(poolId: string, options?: PoolTvlHistoryOptions): Promise<PoolTvlHistoryEntry[]>;
189
+ /**
190
+ * `getPoolTvlHistory` plus `opening` — the newest clearing before the
191
+ * window, read at its own block like every other point, or `null` when
192
+ * the pool has none — from the same read. Pass the result to
193
+ * `combineTvlHistories` as a leg with its `usdRate`: the opening is what
194
+ * the leg held before its first point, so a window cut at a different
195
+ * time on another chain does not count it 0. Same options and errors as
196
+ * `getPoolTvlHistory`; the extra cost is one clearing row (or, for
197
+ * `fromEpoch`, one small request) and one block.
198
+ *
199
+ * ```ts
200
+ * const leg = await kasu.strategies.getPoolTvlHistoryWindow(poolId, { count: 52 });
201
+ * // { entries: PoolTvlHistoryEntry[], opening: PoolTvlHistoryEntry | null }
202
+ * ```
203
+ */
204
+ getPoolTvlHistoryWindow(poolId: string, options?: PoolTvlHistoryOptions): Promise<PoolTvlHistoryResult>;
107
205
  /**
108
206
  * Fetch a single strategy by pool ID. Returns `null` if not found.
109
207
  */
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { selectVisiblePools } from '../domain/pools';
11
+ import { finiteOrUndefined, groupRiskManagementItems, parseFacility, readCmsStartDate, securityStructureOf, splitBusinessTypes, } from '../domain/strategy-details';
11
12
  import { pickShortDescription } from '../domain/strategy-summary';
12
13
  /**
13
14
  * High-level facade for browsing Kasu lending strategies (pools).
@@ -20,10 +21,55 @@ export class StrategiesFacade {
20
21
  * Chain pool id → the pool id its CMS record is keyed by (XDC pools
21
22
  * share their Base counterpart's editorial record). Lowercase keys.
22
23
  */
23
- _poolMetadataMapping = {}) {
24
+ _poolMetadataMapping = {},
25
+ /**
26
+ * The clock the CMS start dates are checked against (a date after it
27
+ * is refused). Injected for tests; the current time otherwise.
28
+ */
29
+ _now = () => new Date(),
30
+ /**
31
+ * Milliseconds on a clock that only moves forward, for the shared
32
+ * CMS reads' 30-second lifetime — separate from `_now`, so a pinned
33
+ * date clock cannot keep a read alive for ever. Injected for tests;
34
+ * `Date.now` otherwise.
35
+ */
36
+ _memoClockMs = () => Date.now()) {
24
37
  this._dataService = _dataService;
25
38
  this._userLending = _userLending;
26
39
  this._poolMetadataMapping = _poolMetadataMapping;
40
+ this._now = _now;
41
+ this._memoClockMs = _memoClockMs;
42
+ /**
43
+ * Short-lived, per-instance memo of the two CMS-wide reads the pool
44
+ * getters share, so a Details screen asking for the loss rate, the risk
45
+ * groups and the originator together reads each collection once. Keyed
46
+ * by read; holds the in-flight promise, so concurrent callers share it.
47
+ * A REJECTED read is dropped at once, never served again — the next call
48
+ * retries.
49
+ */
50
+ this._cmsReads = new Map();
51
+ }
52
+ _memoCmsRead(key, read) {
53
+ const nowMs = this._memoClockMs();
54
+ const cached = this._cmsReads.get(key);
55
+ if (cached && cached.expiresAt > nowMs) {
56
+ return cached.promise;
57
+ }
58
+ const promise = read();
59
+ const entry = { promise, expiresAt: nowMs + CMS_READ_TTL_MS };
60
+ this._cmsReads.set(key, entry);
61
+ promise.catch(() => {
62
+ // Only our own entry: a newer read may have replaced it.
63
+ if (this._cmsReads.get(key) === entry)
64
+ this._cmsReads.delete(key);
65
+ });
66
+ return promise;
67
+ }
68
+ _riskManagementRecords() {
69
+ return this._memoCmsRead('riskManagement', () => this._dataService.getRiskManagement());
70
+ }
71
+ _originatorProfiles() {
72
+ return this._memoCmsRead('originatorProfiles', () => this._dataService.getPoolDelegateProfileAndHistory());
27
73
  }
28
74
  /**
29
75
  * The pool's loss rate and first-loss capital, from its CMS
@@ -36,12 +82,14 @@ export class StrategiesFacade {
36
82
  * 0..1 fraction.
37
83
  *
38
84
  * Requires `directusUrl`; without it the call rejects with
39
- * `NO_DIRECTUS_URL_MESSAGE`, like every CMS-only read.
85
+ * `NO_DIRECTUS_URL_MESSAGE`, like every CMS-only read. Shares its CMS
86
+ * read with `getRiskManagementGroups` for 30 seconds per instance; a
87
+ * failed read is never reused.
40
88
  */
41
89
  getRiskPerformance(poolId) {
42
90
  return __awaiter(this, void 0, void 0, function* () {
43
91
  const metadataId = this._metadataIdOf(poolId);
44
- const records = yield this._dataService.getRiskManagement();
92
+ const records = yield this._riskManagementRecords();
45
93
  const record = records.find((r) => String(r.poolIdFK).toLowerCase() === metadataId);
46
94
  if (!record)
47
95
  return null;
@@ -65,16 +113,95 @@ export class StrategiesFacade {
65
113
  * deployment every profile lists no pools and this resolves `null` —
66
114
  * the same answer kasu-ui's own lookup gives there today. The metadata
67
115
  * candidate becomes live once the service resolves the mapping.
116
+ *
117
+ * Shares its reads with `getOriginatorHistory` for 30 seconds per
118
+ * instance; a failed read is never reused. Each call returns its own
119
+ * copy of the profile, so mutating it changes nothing shared.
68
120
  */
69
121
  getOriginator(poolId) {
70
122
  return __awaiter(this, void 0, void 0, function* () {
71
- var _a;
72
123
  const candidates = new Set([
73
124
  poolId.toLowerCase(),
74
125
  this._metadataIdOf(poolId),
75
126
  ]);
76
- const profiles = yield this._dataService.getPoolDelegateProfileAndHistory();
77
- return ((_a = profiles.find((profile) => profile.otherKASUPools.some((pool) => candidates.has(String(pool.id).toLowerCase())))) !== null && _a !== void 0 ? _a : null);
127
+ const profiles = yield this._originatorProfiles();
128
+ const profile = profiles.find((candidate) => candidate.otherKASUPools.some((pool) => candidates.has(String(pool.id).toLowerCase())));
129
+ // A copy: the profiles are shared between calls (see
130
+ // `_memoCmsRead`), so a caller sorting or editing its result must
131
+ // not change what the next call returns.
132
+ return profile
133
+ ? Object.assign(Object.assign({}, profile), { otherKASUPools: profile.otherKASUPools.map((pool) => (Object.assign({}, pool))) }) : null;
134
+ });
135
+ }
136
+ /**
137
+ * The credit originator's ENTIRE lending history for a pool — since when,
138
+ * total originated, loans outstanding, loss rate — read from the profile
139
+ * `getOriginator` finds, each figure validated. `null` when no profile
140
+ * lists the pool, or the profile authors none of the four.
141
+ *
142
+ * kasu-ui's Details tab shows these as its Credit Originator strip, and
143
+ * hides the strip when there is no profile. The money figures are
144
+ * editorial USD on every deployment: never FX-convert them. An XDC pool
145
+ * resolves `null` today, as it does in kasu-ui (see `getOriginator`).
146
+ *
147
+ * Requires `directusUrl`, like every CMS-only read; rejects when the
148
+ * read fails. Shares its reads with `getOriginator` for 30 seconds per
149
+ * instance; a failed read is never reused.
150
+ */
151
+ getOriginatorHistory(poolId) {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ const profile = yield this.getOriginator(poolId);
154
+ if (!profile)
155
+ return null;
156
+ const history = {};
157
+ const since = readCmsStartDate(profile.delegateLendingHistory, this._now(), { unixSeconds: true });
158
+ if (since !== undefined)
159
+ history.since = since;
160
+ const totalOriginated = finiteOrUndefined(profile.totalLoanFundsOriginated);
161
+ if (totalOriginated !== undefined) {
162
+ history.totalOriginated = totalOriginated;
163
+ }
164
+ const loansOutstanding = finiteOrUndefined(profile.loansUnderManagement);
165
+ if (loansOutstanding !== undefined) {
166
+ history.loansOutstanding = loansOutstanding;
167
+ }
168
+ const lossRate = finiteOrUndefined(profile.historicLossRate);
169
+ if (lossRate !== undefined)
170
+ history.lossRate = lossRate;
171
+ return Object.keys(history).length > 0 ? history : null;
172
+ });
173
+ }
174
+ /**
175
+ * The pool's Risk Management groups, from its CMS risk-management record:
176
+ * each group with its items (name, the pool's description of it split
177
+ * into lines, the shared tooltip), the groups in `RISK_GROUP_ORDER`
178
+ * (Security & Recourse, Structural Controls, Financial Covenants,
179
+ * Reporting Covenants, Key Eligibility Criteria, then any other in CMS
180
+ * order). See `groupRiskManagementItems`.
181
+ *
182
+ * `null` when the pool has no record, or the record has no usable item —
183
+ * then kasu-ui falls back to `Strategy.securityStructure`. XDC pools
184
+ * resolve through the metadata mapping to their Base record, like
185
+ * `getRiskPerformance`.
186
+ *
187
+ * REJECTS when the CMS read fails (an outage, or no `directusUrl` —
188
+ * `NO_DIRECTUS_URL_MESSAGE`), so a failure stays visible rather than
189
+ * reading as "no items". For what to SHOW, treat a rejection like `null`:
190
+ * fall back to `Strategy.securityStructure`, which arrives with the
191
+ * strategy and needs no second read.
192
+ *
193
+ * Shares its CMS read with `getRiskPerformance` for 30 seconds per
194
+ * instance; a failed read is never reused.
195
+ */
196
+ getRiskManagementGroups(poolId) {
197
+ return __awaiter(this, void 0, void 0, function* () {
198
+ const metadataId = this._metadataIdOf(poolId);
199
+ const records = yield this._riskManagementRecords();
200
+ const record = records.find((r) => String(r.poolIdFK).toLowerCase() === metadataId);
201
+ if (!record || !Array.isArray(record.items))
202
+ return null;
203
+ const groups = groupRiskManagementItems(record.items);
204
+ return groups.length > 0 ? groups : null;
78
205
  });
79
206
  }
80
207
  _metadataIdOf(poolId) {
@@ -153,6 +280,26 @@ export class StrategiesFacade {
153
280
  return yield this._dataService.getPoolTvlHistory(poolId, options);
154
281
  });
155
282
  }
283
+ /**
284
+ * `getPoolTvlHistory` plus `opening` — the newest clearing before the
285
+ * window, read at its own block like every other point, or `null` when
286
+ * the pool has none — from the same read. Pass the result to
287
+ * `combineTvlHistories` as a leg with its `usdRate`: the opening is what
288
+ * the leg held before its first point, so a window cut at a different
289
+ * time on another chain does not count it 0. Same options and errors as
290
+ * `getPoolTvlHistory`; the extra cost is one clearing row (or, for
291
+ * `fromEpoch`, one small request) and one block.
292
+ *
293
+ * ```ts
294
+ * const leg = await kasu.strategies.getPoolTvlHistoryWindow(poolId, { count: 52 });
295
+ * // { entries: PoolTvlHistoryEntry[], opening: PoolTvlHistoryEntry | null }
296
+ * ```
297
+ */
298
+ getPoolTvlHistoryWindow(poolId_1) {
299
+ return __awaiter(this, arguments, void 0, function* (poolId, options = {}) {
300
+ return yield this._dataService.getPoolTvlHistoryWindow(poolId, options);
301
+ });
302
+ }
156
303
  /**
157
304
  * Fetch a single strategy by pool ID. Returns `null` if not found.
158
305
  */
@@ -228,10 +375,39 @@ export class StrategiesFacade {
228
375
  apyStructure: pool.poolApyStructure,
229
376
  thumbnailUrl: pool.thumbnailImageUrl,
230
377
  bannerUrl: pool.bannerImageUrl,
378
+ strategyHistory: strategyHistoryOf(pool, this._now()),
379
+ endBorrowers: endBorrowersOf(pool),
380
+ securityStructure: securityStructureOf(pool.security),
231
381
  _raw: pool,
232
382
  };
233
383
  }
234
384
  }
385
+ /**
386
+ * How long a CMS-wide read is shared between the pool getters. Long enough
387
+ * for one screen's worth of calls, short enough that a CMS edit shows on the
388
+ * next visit; apps cache further on their own terms.
389
+ */
390
+ const CMS_READ_TTL_MS = 30000;
391
+ /** `Strategy.strategyHistory`: an absent figure is an absent key. */
392
+ function strategyHistoryOf(pool, now) {
393
+ const history = {};
394
+ const since = readCmsStartDate(pool.operatingSince, now);
395
+ if (since !== undefined)
396
+ history.since = since;
397
+ const lenderInterestEarned = finiteOrUndefined(pool.yieldEarned);
398
+ if (lenderInterestEarned !== undefined) {
399
+ history.lenderInterestEarned = lenderInterestEarned;
400
+ }
401
+ return history;
402
+ }
403
+ /** Business Types and Facility Type, or `undefined` when neither is authored. */
404
+ function endBorrowersOf(pool) {
405
+ const businessTypes = splitBusinessTypes(pool.industryExposure);
406
+ const facility = parseFacility(pool.loanStructure);
407
+ if (!businessTypes && !facility)
408
+ return undefined;
409
+ return Object.assign(Object.assign({}, (businessTypes ? { businessTypes } : {})), (facility ? { facility } : {}));
410
+ }
235
411
  /**
236
412
  * A CMS text field as a string, or `undefined` when it is absent, not a
237
413
  * string, or empty (blank included) — the CMS stores an emptied field as `''`, and an empty
@@ -1 +1 @@
1
- {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../src/facade/strategies.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../src/facade/strategies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { ChainConfigEntry, SupportedChain } from './types';
2
+ /**
3
+ * Strategy ↔ deployment resolution. A lending strategy is not tied to one
4
+ * deployment: Tax Pay runs as one pool on Base (USDC) and another on XDC
5
+ * (AUDD), and the two share one CMS record keyed by the BASE pool id — the
6
+ * canonical id. Each chain config's `poolMetadataMapping` maps its
7
+ * chain-local ids to canonical ones; Base, being canonical, has none.
8
+ *
9
+ * Pure: it reads only the built-in `CHAIN_CONFIGS`. The same rules as
10
+ * kasu-ui's counterpart lookup, so both apps sum a strategy over the same
11
+ * pools.
12
+ */
13
+ /** The pool that represents a strategy on one deployment. */
14
+ export interface StrategyDeployment {
15
+ chain: SupportedChain;
16
+ /**
17
+ * Chain-local pool id, lowercase — what that chain's subgraph is keyed
18
+ * by.
19
+ */
20
+ poolId: string;
21
+ }
22
+ /**
23
+ * What `strategyDeployments` refuses, as a code:
24
+ *
25
+ * - `pool-id` — not a `0x` address;
26
+ * - `chain` — not a `SupportedChain`;
27
+ * - `wrong-chain` — the mapping places the id on ANOTHER deployment (an XDC
28
+ * chain-local id passed as Base, or a Base id passed as XDC). Querying one
29
+ * chain with another's address reads nothing, silently.
30
+ */
31
+ export type StrategyDeploymentInputErrorCode = 'pool-id' | 'chain' | 'wrong-chain';
32
+ /** What `strategyDeployments` throws for an id it cannot place. */
33
+ export declare class StrategyDeploymentInputError extends Error {
34
+ readonly code: StrategyDeploymentInputErrorCode;
35
+ constructor(code: StrategyDeploymentInputErrorCode);
36
+ }
37
+ type MappingConfigs = Readonly<Record<SupportedChain, Pick<ChainConfigEntry, 'poolMetadataMapping'>>>;
38
+ /**
39
+ * `strategyDeployments` over any configs — the export reads `CHAIN_CONFIGS`;
40
+ * the spec passes its own to cover shapes the built-in mapping lacks.
41
+ */
42
+ export declare function resolveStrategyDeployments(configs: MappingConfigs, poolId: string, chain: SupportedChain): StrategyDeployment[];
43
+ /**
44
+ * Every deployment a strategy has a pool on, canonical (Base) first, then the
45
+ * others in `CHAIN_CONFIGS` order — the legs to fetch and pass to
46
+ * `combineTvlHistories`. One entry for a strategy that lives on one chain
47
+ * only (PayFi, on Base).
48
+ *
49
+ * `chain` is the deployment `poolId` was read on — required, because an
50
+ * address alone does not say which chain it belongs to. From either side of
51
+ * a mapping the answer is the same set: Tax Pay's Base id on `'base'` and
52
+ * its XDC id on `'xdc'` both return both pools. An id the mapping does not
53
+ * know is a strategy of one on its own chain. Ids are compared
54
+ * case-insensitively and returned lowercase.
55
+ *
56
+ * Throws `StrategyDeploymentInputError` for a malformed id, an unknown chain,
57
+ * or an id the mapping places on another deployment (`'wrong-chain'`).
58
+ *
59
+ * ```ts
60
+ * strategyDeployments(strategy.id, 'base');
61
+ * // [{ chain: 'base', poolId: '0x…' }, { chain: 'xdc', poolId: '0x…' }]
62
+ * ```
63
+ */
64
+ export declare function strategyDeployments(poolId: string, chain: SupportedChain): StrategyDeployment[];
65
+ export {};
@@ -0,0 +1,97 @@
1
+ import { CHAIN_CONFIGS } from './chain-configs';
2
+ /** What `strategyDeployments` throws for an id it cannot place. */
3
+ export class StrategyDeploymentInputError extends Error {
4
+ constructor(code) {
5
+ super(`strategyDeployments: input refused (${code})`);
6
+ this.name = 'StrategyDeploymentInputError';
7
+ this.code = code;
8
+ Object.setPrototypeOf(this, StrategyDeploymentInputError.prototype);
9
+ }
10
+ }
11
+ /** The canonical deployment: its pool ids ARE the strategies' ids. */
12
+ const CANONICAL_CHAIN = 'base';
13
+ const ADDRESS_RE = /^0x[0-9a-f]{40}$/;
14
+ /** The deployment's mapping with both sides lowercased; Base never has one. */
15
+ function mappingOf(configs, chain) {
16
+ var _a;
17
+ if (chain === CANONICAL_CHAIN)
18
+ return [];
19
+ return Object.entries((_a = configs[chain].poolMetadataMapping) !== null && _a !== void 0 ? _a : {}).map(([local, canonical]) => [local.toLowerCase(), canonical.toLowerCase()]);
20
+ }
21
+ /**
22
+ * `strategyDeployments` over any configs — the export reads `CHAIN_CONFIGS`;
23
+ * the spec passes its own to cover shapes the built-in mapping lacks.
24
+ */
25
+ export function resolveStrategyDeployments(configs, poolId, chain) {
26
+ const id = typeof poolId === 'string' ? poolId.trim().toLowerCase() : '';
27
+ if (!ADDRESS_RE.test(id)) {
28
+ throw new StrategyDeploymentInputError('pool-id');
29
+ }
30
+ if (typeof chain !== 'string' ||
31
+ !Object.prototype.hasOwnProperty.call(configs, chain)) {
32
+ throw new StrategyDeploymentInputError('chain');
33
+ }
34
+ const chains = Object.keys(configs);
35
+ const mappings = chains.map((c) => [c, mappingOf(configs, c)]);
36
+ const isLocalElsewhere = mappings.some(([c, mapping]) => c !== chain && mapping.some(([local]) => local === id));
37
+ let canonical;
38
+ if (chain === CANONICAL_CHAIN) {
39
+ // A Base id is its own Base pool — unless the mapping says it is
40
+ // another deployment's chain-local id, which names no Base pool.
41
+ if (isLocalElsewhere) {
42
+ throw new StrategyDeploymentInputError('wrong-chain');
43
+ }
44
+ canonical = id;
45
+ }
46
+ else {
47
+ const own = mappingOf(configs, chain).find(([local]) => local === id);
48
+ if (own) {
49
+ canonical = own[1];
50
+ }
51
+ else {
52
+ const isCanonical = mappings.some(([, mapping]) => mapping.some(([, target]) => target === id));
53
+ if (isLocalElsewhere || isCanonical) {
54
+ throw new StrategyDeploymentInputError('wrong-chain');
55
+ }
56
+ // Unmapped off Base: a strategy of one on its own chain (every
57
+ // XDC USDC pool today). Claiming a Base counterpart would read
58
+ // Base with an XDC address.
59
+ return [{ chain, poolId: id }];
60
+ }
61
+ }
62
+ const found = [
63
+ { chain: CANONICAL_CHAIN, poolId: canonical },
64
+ ];
65
+ for (const [c, mapping] of mappings) {
66
+ for (const [local, target] of mapping) {
67
+ if (target === canonical)
68
+ found.push({ chain: c, poolId: local });
69
+ }
70
+ }
71
+ return found;
72
+ }
73
+ /**
74
+ * Every deployment a strategy has a pool on, canonical (Base) first, then the
75
+ * others in `CHAIN_CONFIGS` order — the legs to fetch and pass to
76
+ * `combineTvlHistories`. One entry for a strategy that lives on one chain
77
+ * only (PayFi, on Base).
78
+ *
79
+ * `chain` is the deployment `poolId` was read on — required, because an
80
+ * address alone does not say which chain it belongs to. From either side of
81
+ * a mapping the answer is the same set: Tax Pay's Base id on `'base'` and
82
+ * its XDC id on `'xdc'` both return both pools. An id the mapping does not
83
+ * know is a strategy of one on its own chain. Ids are compared
84
+ * case-insensitively and returned lowercase.
85
+ *
86
+ * Throws `StrategyDeploymentInputError` for a malformed id, an unknown chain,
87
+ * or an id the mapping places on another deployment (`'wrong-chain'`).
88
+ *
89
+ * ```ts
90
+ * strategyDeployments(strategy.id, 'base');
91
+ * // [{ chain: 'base', poolId: '0x…' }, { chain: 'xdc', poolId: '0x…' }]
92
+ * ```
93
+ */
94
+ export function strategyDeployments(poolId, chain) {
95
+ return resolveStrategyDeployments(CHAIN_CONFIGS, poolId, chain);
96
+ }
97
+ //# sourceMappingURL=strategy-deployments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-deployments.js","sourceRoot":"","sources":["../../src/facade/strategy-deployments.ts"],"names":[],"mappings":"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"}