@kasufinance/kasu-sdk 2.13.0 → 2.14.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.
@@ -15500,6 +15500,185 @@ KasuPoolExternalTVLAbi__factory.abi = _abi;
15500
15500
  function poolTvl(onChainBalance, offChainTvl) {
15501
15501
  return parseFloat(onChainBalance) + parseFloat(offChainTvl);
15502
15502
  }
15503
+ /**
15504
+ * What `combineTvlHistories` throws instead of returning a number it cannot
15505
+ * stand behind. `leg` and `entry` are the zero-based position of the
15506
+ * offending input, when there is one.
15507
+ */
15508
+ class TvlHistoryInputError extends Error {
15509
+ constructor(code, leg, entry) {
15510
+ const at = [
15511
+ leg === undefined ? '' : ` at leg ${String(leg)}`,
15512
+ entry === undefined ? '' : `, entry ${String(entry)}`,
15513
+ ].join('');
15514
+ super(`combineTvlHistories: input refused (${code})${at}`);
15515
+ this.name = 'TvlHistoryInputError';
15516
+ this.code = code;
15517
+ this.leg = leg;
15518
+ this.entry = entry;
15519
+ Object.setPrototypeOf(this, TvlHistoryInputError.prototype);
15520
+ }
15521
+ }
15522
+ function isNonNegativeFinite(value) {
15523
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
15524
+ }
15525
+ /**
15526
+ * Throws unless the leg is well formed. Index loops, not `forEach`: a hole in
15527
+ * a sparse array is skipped by the array methods and would surface later as
15528
+ * a raw `TypeError` instead of a refusal.
15529
+ */
15530
+ function validateLeg(leg, legIndex) {
15531
+ if (typeof leg !== 'object' || leg === null) {
15532
+ throw new TvlHistoryInputError('leg', legIndex);
15533
+ }
15534
+ const { entries, usdRate, opening } = leg;
15535
+ if (typeof usdRate !== 'number' ||
15536
+ !Number.isFinite(usdRate) ||
15537
+ usdRate <= 0) {
15538
+ throw new TvlHistoryInputError('usd-rate', legIndex);
15539
+ }
15540
+ if (!Array.isArray(entries)) {
15541
+ throw new TvlHistoryInputError('entries', legIndex);
15542
+ }
15543
+ const list = entries;
15544
+ if (list.length === 0) {
15545
+ throw new TvlHistoryInputError('empty-leg', legIndex);
15546
+ }
15547
+ let previous = -Infinity;
15548
+ for (let index = 0; index < list.length; index += 1) {
15549
+ const entry = list[index];
15550
+ if (typeof entry !== 'object' || entry === null) {
15551
+ throw new TvlHistoryInputError('entry', legIndex, index);
15552
+ }
15553
+ const { timestamp, tvl, kind } = entry;
15554
+ if (!isNonNegativeFinite(timestamp)) {
15555
+ throw new TvlHistoryInputError('timestamp', legIndex, index);
15556
+ }
15557
+ if (!isNonNegativeFinite(tvl)) {
15558
+ throw new TvlHistoryInputError('tvl', legIndex, index);
15559
+ }
15560
+ if (kind !== 'clearing' && kind !== 'current') {
15561
+ throw new TvlHistoryInputError('kind', legIndex, index);
15562
+ }
15563
+ if (kind === 'current' && index !== list.length - 1) {
15564
+ throw new TvlHistoryInputError('current', legIndex, index);
15565
+ }
15566
+ if (timestamp < previous) {
15567
+ throw new TvlHistoryInputError('order', legIndex, index);
15568
+ }
15569
+ previous = timestamp;
15570
+ }
15571
+ if (opening !== undefined && opening !== null) {
15572
+ const first = list[0];
15573
+ const { timestamp, tvl, kind } = (typeof opening === 'object' ? opening : {});
15574
+ if (!isNonNegativeFinite(timestamp) ||
15575
+ !isNonNegativeFinite(tvl) ||
15576
+ kind !== 'clearing' ||
15577
+ timestamp > first.timestamp) {
15578
+ throw new TvlHistoryInputError('opening', legIndex);
15579
+ }
15580
+ }
15581
+ return leg;
15582
+ }
15583
+ /**
15584
+ * A strategy's TVL in USD over time, from its deployments' histories — Tax
15585
+ * Pay runs on Base (USDC) and on XDC (AUDD), and its total lent is both.
15586
+ * Pure: the caller fetches each leg (`strategyDeployments` names them) and
15587
+ * passes the exchange rates.
15588
+ *
15589
+ * A step merge by time. At every distinct timestamp where any leg has a
15590
+ * clearing, the value is the sum over legs of that leg's latest point at or
15591
+ * before then, times its `usdRate`. A leg's `opening` — what it held just
15592
+ * before the window — is one more step: it counts from its own timestamp
15593
+ * until the leg's first entry, and the leg is 0 before it (or throughout,
15594
+ * before its first entry, without one).
15595
+ * Points that share a timestamp — clearings run in one block, or two chains
15596
+ * clearing in the same second — are one output point. The series ends with
15597
+ * one `current` point at the latest of the legs' `current` timestamps, equal
15598
+ * to the sum of their `current` values. Every leg must end in a `current`
15599
+ * point, or none may.
15600
+ *
15601
+ * The window is the union of the legs' windows: the series starts at the
15602
+ * earliest first entry of any leg. An `opening` is a value, never a point.
15603
+ * Without it, two windows cut at offset clearing times would count the
15604
+ * later-starting leg 0 at the left edge and draw a false step up; with it,
15605
+ * only a genuine late start (`opening: null`) counts 0.
15606
+ *
15607
+ * Every leg and entry is validated first: a bad input — an empty leg
15608
+ * included — throws `TvlHistoryInputError` (its `code` says why), so the
15609
+ * result never holds `NaN` or `Infinity`. The inputs are not modified.
15610
+ *
15611
+ * ```ts
15612
+ * const window = { count: 52 };
15613
+ * const points = combineTvlHistories([
15614
+ * { ...(await base.strategies.getPoolTvlHistoryWindow(basePool, window)), usdRate: 1 },
15615
+ * { ...(await xdc.strategies.getPoolTvlHistoryWindow(xdcPool, window)), usdRate: audToUsd },
15616
+ * ]);
15617
+ * ```
15618
+ */
15619
+ function combineTvlHistories(legs) {
15620
+ if (!Array.isArray(legs) || legs.length === 0) {
15621
+ throw new TvlHistoryInputError('legs');
15622
+ }
15623
+ const valid = [];
15624
+ for (let index = 0; index < legs.length; index += 1) {
15625
+ valid.push(validateLeg(legs[index], index));
15626
+ }
15627
+ const endsInCurrent = valid.map((leg) => leg.entries[leg.entries.length - 1].kind === 'current');
15628
+ const odd = endsInCurrent.findIndex((ends) => ends !== endsInCurrent[0]);
15629
+ if (odd !== -1)
15630
+ throw new TvlHistoryInputError('current', odd);
15631
+ const finalTimestamp = endsInCurrent[0]
15632
+ ? Math.max(...valid.map((leg) => leg.entries[leg.entries.length - 1].timestamp))
15633
+ : undefined;
15634
+ const clearingTimes = [
15635
+ ...new Set(valid.flatMap((leg) => leg.entries
15636
+ .filter((entry) => entry.kind === 'clearing')
15637
+ .map((entry) => entry.timestamp))),
15638
+ ]
15639
+ .filter((t) => finalTimestamp === undefined || t < finalTimestamp)
15640
+ .sort((a, b) => a - b);
15641
+ // One cursor per leg: the times ascend, so each leg is walked once. A
15642
+ // leg's `current` point is a step like any other, which keeps a chain
15643
+ // whose subgraph lags behind the other's last clearing at its own latest.
15644
+ const cursors = valid.map(() => -1);
15645
+ const sumAt = (t) => {
15646
+ let sum = 0;
15647
+ valid.forEach((leg, index) => {
15648
+ let cursor = cursors[index];
15649
+ while (cursor + 1 < leg.entries.length &&
15650
+ leg.entries[cursor + 1].timestamp <= t) {
15651
+ cursor += 1;
15652
+ }
15653
+ cursors[index] = cursor;
15654
+ // Before the first entry, the opening is the step — from its
15655
+ // own time on, never earlier.
15656
+ const opening = leg.opening;
15657
+ const value = cursor >= 0
15658
+ ? leg.entries[cursor].tvl
15659
+ : opening && opening.timestamp <= t
15660
+ ? opening.tvl
15661
+ : 0;
15662
+ sum += value * leg.usdRate;
15663
+ });
15664
+ if (!Number.isFinite(sum))
15665
+ throw new TvlHistoryInputError('overflow');
15666
+ return sum;
15667
+ };
15668
+ const combined = clearingTimes.map((t) => ({
15669
+ timestamp: t,
15670
+ tvlUsd: sumAt(t),
15671
+ kind: 'clearing',
15672
+ }));
15673
+ if (finalTimestamp !== undefined) {
15674
+ combined.push({
15675
+ timestamp: finalTimestamp,
15676
+ tvlUsd: sumAt(finalTimestamp),
15677
+ kind: 'current',
15678
+ });
15679
+ }
15680
+ return combined;
15681
+ }
15503
15682
 
15504
15683
  /**
15505
15684
  * Epochs in a year — the single source of truth for every rate conversion in
@@ -16248,6 +16427,95 @@ function fetchPoolClearings(request, poolId, scope, cancellation) {
16248
16427
  return { clearings, snapshot, requests };
16249
16428
  });
16250
16429
  }
16430
+ /**
16431
+ * Pure: the opening clearing — the newest of `before` (finished clearings the
16432
+ * window left out, older by epoch) that finished STRICTLY before the first
16433
+ * in-window clearing's block. Newest by block, then epoch, so a clearing
16434
+ * numbered out of order (XDC AUDD's epoch 1, a week before epoch 88) is
16435
+ * placed by when it happened. A clearing in the first in-window block itself
16436
+ * (a catch-up block that finished several epochs at once) is not an opening:
16437
+ * it holds the first entry's own value, not the one before it. `null` when
16438
+ * there is none — see `needsClearingBeforeBlock`.
16439
+ */
16440
+ function pickOpeningClearing(before, inWindow) {
16441
+ const firstBlock = Math.min(...inWindow.map((c) => c.block));
16442
+ let opening = null;
16443
+ for (const clearing of before) {
16444
+ if (clearing.block >= firstBlock)
16445
+ continue;
16446
+ if (opening === null ||
16447
+ clearing.block > opening.block ||
16448
+ (clearing.block === opening.block &&
16449
+ clearing.epochId > opening.epochId)) {
16450
+ opening = clearing;
16451
+ }
16452
+ }
16453
+ return opening;
16454
+ }
16455
+ /**
16456
+ * Pure: whether the opening needs `fetchClearingBefore`'s by-block read.
16457
+ * Only when the window left clearings out but every one of them finished in
16458
+ * or after the first in-window block — the extra rows sat in a catch-up
16459
+ * block — so an older one, if any, was not fetched. Otherwise the opening
16460
+ * (or its absence) is already known and nothing more is read.
16461
+ */
16462
+ function needsClearingBeforeBlock(before, opening) {
16463
+ return opening === null && before.length > 0;
16464
+ }
16465
+ /**
16466
+ * The newest finished clearing in a block below `blockLt`, by block: the
16467
+ * opening when every clearing the window left out shares its first block.
16468
+ * ONE extra request for one row, no snapshot. Clearings that share that
16469
+ * older block share its time and balance, so which one comes back does not
16470
+ * change the value.
16471
+ */
16472
+ const poolTvlClearingBeforeBlockQuery = gql `
16473
+ query PoolTvlClearingBeforeBlock($pool: String!, $blockLt: BigInt!) {
16474
+ clearings: lendingPoolClearings(
16475
+ first: 1
16476
+ orderBy: endBlockNumber
16477
+ orderDirection: desc
16478
+ where: {
16479
+ lendingPool: $pool
16480
+ isFinished: true
16481
+ endBlockNumber_lt: $blockLt
16482
+ }
16483
+ ) {
16484
+ epochId
16485
+ endBlockNumber
16486
+ endTimestamp
16487
+ }
16488
+ }
16489
+ `;
16490
+ function fetchClearingBeforeBlock(request, poolId, blockLt, cancellation) {
16491
+ return __awaiter(this, void 0, void 0, function* () {
16492
+ cancellation.throwIfCancelled();
16493
+ const page = yield request(poolTvlClearingBeforeBlockQuery, { pool: poolId, blockLt: String(blockLt) }, cancellation.signal);
16494
+ const row = page.clearings.at(0);
16495
+ return row === undefined ? null : parseClearing(row);
16496
+ });
16497
+ }
16498
+ /**
16499
+ * The newest finished clearing numbered below `beforeEpoch`: the opening
16500
+ * candidate of a `fromEpoch` window, whose own fetch never reads that far
16501
+ * back. ONE extra request for one row, no snapshot.
16502
+ */
16503
+ function fetchClearingBefore(request, poolId, beforeEpoch, cancellation) {
16504
+ return __awaiter(this, void 0, void 0, function* () {
16505
+ cancellation.throwIfCancelled();
16506
+ const page = yield request(poolTvlClearingsQuery, {
16507
+ poolId,
16508
+ pool: poolId,
16509
+ epochGte: '0',
16510
+ epochLt: String(beforeEpoch),
16511
+ direction: 'desc',
16512
+ first: 1,
16513
+ withSnapshot: false,
16514
+ }, cancellation.signal);
16515
+ const row = page.clearings.at(0);
16516
+ return row === undefined ? null : parseClearing(row);
16517
+ });
16518
+ }
16251
16519
  /**
16252
16520
  * The pool's balance (display units, the subgraph's decimal string) at the end
16253
16521
  * of each block, `TVL_HISTORY_BLOCKS_PER_REQUEST` blocks per request. A block
@@ -16651,6 +16919,42 @@ class DataService {
16651
16919
  */
16652
16920
  getPoolTvlHistory(poolId_1) {
16653
16921
  return __awaiter(this, arguments, void 0, function* (poolId, options = {}) {
16922
+ return (yield this._poolTvlHistory(poolId, options, false)).entries;
16923
+ });
16924
+ }
16925
+ /**
16926
+ * `getPoolTvlHistory` — the same options, errors and `entries` — plus
16927
+ * `opening`: the pool's value just before the window, so a strategy
16928
+ * summed across deployments (`combineTvlHistories`) knows what each leg
16929
+ * held before its first point instead of counting it 0.
16930
+ *
16931
+ * `opening` is the newest finished clearing STRICTLY before the window's
16932
+ * first block (by `pickOpeningClearing`), read at its own block exactly
16933
+ * like every other point and through the same past-block cache; `null`
16934
+ * when the pool has no clearing before the window. Extra cost over
16935
+ * `getPoolTvlHistory`:
16936
+ *
16937
+ * - `count` only: one more clearing row in the same request (`count + 1`,
16938
+ * which always reaches past the window when older history exists);
16939
+ * - `fromEpoch` above 0: one more one-row subgraph request, in parallel
16940
+ * with the clearings;
16941
+ * - only when every left-out clearing finished in the window's first
16942
+ * block (a catch-up block that closed several epochs at once): one
16943
+ * more one-row request by block (`fetchClearingBeforeBlock`), after
16944
+ * the clearings — the common case never makes it;
16945
+ * - either way, the opening's block in the same batched time-travel read
16946
+ * and one more `externalTVLOfPool` read (cached once final).
16947
+ *
16948
+ * `{ entries: [], opening: null }` wherever `getPoolTvlHistory` returns
16949
+ * `[]`.
16950
+ */
16951
+ getPoolTvlHistoryWindow(poolId_1) {
16952
+ return __awaiter(this, arguments, void 0, function* (poolId, options = {}) {
16953
+ return yield this._poolTvlHistory(poolId, options, true);
16954
+ });
16955
+ }
16956
+ _poolTvlHistory(poolId, options, withOpening) {
16957
+ return __awaiter(this, void 0, void 0, function* () {
16654
16958
  var _a;
16655
16959
  validatePoolTvlHistoryOptions(options);
16656
16960
  if (!isAddress(poolId)) {
@@ -16669,33 +16973,56 @@ class DataService {
16669
16973
  rpcs,
16670
16974
  cancellation,
16671
16975
  })
16672
- : null, externalTvl !== null && externalTvl !== void 0 ? externalTvl : '', cancellation));
16976
+ : null, externalTvl !== null && externalTvl !== void 0 ? externalTvl : '', cancellation, withOpening));
16673
16977
  });
16674
16978
  }
16675
- _readPoolTvlHistory(pool, options, reader, externalTvl, cancellation) {
16979
+ _readPoolTvlHistory(pool, options, reader, externalTvl, cancellation, withOpening) {
16676
16980
  return __awaiter(this, void 0, void 0, function* () {
16677
16981
  var _a, _b, _c;
16982
+ const nothing = { entries: [], opening: null };
16678
16983
  const graph = (document, variables, signal) => this._graph.request({ document, variables, signal });
16679
16984
  const scope = options.fromEpoch === undefined && options.count !== undefined
16680
- ? { kind: 'newest', count: options.count }
16985
+ ? {
16986
+ kind: 'newest',
16987
+ // One past the window: the opening, when there is one.
16988
+ count: options.count + (withOpening ? 1 : 0),
16989
+ }
16681
16990
  : { kind: 'from', fromEpoch: (_a = options.fromEpoch) !== null && _a !== void 0 ? _a : 0 };
16682
16991
  try {
16683
- const [currentEpochNumber, { clearings, snapshot }] = yield Promise.all([
16992
+ const [currentEpochNumber, { clearings, snapshot }, before] = yield Promise.all([
16684
16993
  this._systemVariablesAbi.currentEpochNumber(),
16685
16994
  fetchPoolClearings(graph, pool, scope, cancellation),
16995
+ withOpening && scope.kind === 'from' && scope.fromEpoch > 0
16996
+ ? fetchClearingBefore(graph, pool, scope.fromEpoch, cancellation)
16997
+ : Promise.resolve(null),
16686
16998
  ]);
16687
16999
  const currentEpoch = currentEpochNumber.toNumber();
16688
17000
  const window = resolvePoolTvlHistoryWindow(options, currentEpoch);
16689
17001
  const poolNow = snapshot.pool;
16690
17002
  if (!window || !poolNow)
16691
- return [];
17003
+ return nothing;
16692
17004
  const head = (_b = snapshot.meta) === null || _b === void 0 ? void 0 : _b.block;
16693
17005
  if (!head || typeof head.timestamp !== 'number') {
16694
17006
  throw new Error('getPoolTvlHistory: the subgraph returned no latest block time');
16695
17007
  }
16696
17008
  const inWindow = clearings.filter((c) => c.epochId >= window.fromEpoch &&
16697
17009
  c.epochId <= window.toEpoch);
16698
- const blocks = distinctBlocks(inWindow);
17010
+ // Clearings the window left out, older by epoch: the extra row of
17011
+ // a count fetch, or the one-row read below `fromEpoch`.
17012
+ const older = scope.kind === 'newest'
17013
+ ? clearings.filter((c) => c.epochId < window.fromEpoch)
17014
+ : before === null
17015
+ ? []
17016
+ : [before];
17017
+ let opening = withOpening
17018
+ ? pickOpeningClearing(older, inWindow)
17019
+ : null;
17020
+ // The left-out clearings all sat in the first in-window block (a
17021
+ // catch-up block): ask for the newest one before it, by block.
17022
+ if (withOpening && needsClearingBeforeBlock(older, opening)) {
17023
+ opening = yield fetchClearingBeforeBlock(graph, pool, Math.min(...inWindow.map((c) => c.block)), cancellation);
17024
+ }
17025
+ const blocks = distinctBlocks(opening ? [...inWindow, opening] : inWindow);
16699
17026
  const withCurrent = window.toEpoch >= currentEpoch;
16700
17027
  const cacheable = (block) => block <= head.number - TVL_HISTORY_CACHE_DEPTH;
16701
17028
  const [balances, offChainRead] = yield Promise.all([
@@ -16713,7 +17040,7 @@ class DataService {
16713
17040
  latest: null,
16714
17041
  },
16715
17042
  ]);
16716
- return buildPoolTvlHistory({
17043
+ const entries = buildPoolTvlHistory({
16717
17044
  clearings: inWindow,
16718
17045
  balances,
16719
17046
  offChain: offChainRead.offChain,
@@ -16727,10 +17054,22 @@ class DataService {
16727
17054
  : null,
16728
17055
  decimals: this._kasuConfig.stableAssetDecimals,
16729
17056
  });
17057
+ // The same function as every other point, so the opening cannot
17058
+ // be computed another way.
17059
+ const [openingEntry] = opening
17060
+ ? buildPoolTvlHistory({
17061
+ clearings: [opening],
17062
+ balances,
17063
+ offChain: offChainRead.offChain,
17064
+ current: null,
17065
+ decimals: this._kasuConfig.stableAssetDecimals,
17066
+ })
17067
+ : [null];
17068
+ return { entries, opening: openingEntry };
16730
17069
  }
16731
17070
  catch (error) {
16732
17071
  if (isEmptyHistoryError(error, this._kasuConfig.isLiteDeployment)) {
16733
- return [];
17072
+ return nothing;
16734
17073
  }
16735
17074
  throw error;
16736
17075
  }
@@ -18013,14 +18352,13 @@ const currentEpochFtdAmountQuery = gql `
18013
18352
  user: $userId
18014
18353
  lendingPool_in: $poolIds
18015
18354
  epochId: $currentEpoch
18355
+ type: DepositRequest
18016
18356
  }
18017
18357
  ) {
18018
18358
  fixedTermConfigId
18019
18359
  amountRequested
18020
18360
  tranche {
18021
18361
  id
18022
- balance
18023
- shares
18024
18362
  }
18025
18363
  }
18026
18364
  }
@@ -18035,11 +18373,7 @@ const currentFtdBalanceQuery = gql `
18035
18373
  configId
18036
18374
  lendingPoolTranche {
18037
18375
  id
18038
- }
18039
- }
18040
- lendingPool {
18041
- balance
18042
- tranches {
18376
+ balance
18043
18377
  shares
18044
18378
  }
18045
18379
  }
@@ -18047,6 +18381,13 @@ const currentFtdBalanceQuery = gql `
18047
18381
  }
18048
18382
  `;
18049
18383
 
18384
+ /** Thrown when the subgraph reports a request type with no known unit. */
18385
+ const UNKNOWN_REQUEST_TYPE_MESSAGE = 'UserLending: unknown request type, its amount unit is unknown';
18386
+ const KNOWN_REQUEST_TYPES = [
18387
+ 'DepositRequest',
18388
+ 'WithdrawalRequest',
18389
+ ];
18390
+ const isKnownRequestType = (type) => typeof type === 'string' && KNOWN_REQUEST_TYPES.includes(type);
18050
18391
  class UserLending {
18051
18392
  constructor(_kasuConfig, signerOrProvider) {
18052
18393
  this._kasuConfig = _kasuConfig;
@@ -18208,6 +18549,14 @@ class UserLending {
18208
18549
  ]);
18209
18550
  const retn = [];
18210
18551
  for (const userRequest of subgraphResult.userRequests) {
18552
+ // A request type this SDK does not know has no known amount unit
18553
+ // (the schema also declares types no live deployment emits yet).
18554
+ // Skip that ONE row before anything is priced or read on chain,
18555
+ // rather than failing — and blanking — the lender's whole list.
18556
+ if (!isKnownRequestType(userRequest.type)) {
18557
+ console.error(`${UNKNOWN_REQUEST_TYPE_MESSAGE}: ${String(userRequest.type)} (request ${userRequest.id}); row skipped`);
18558
+ continue;
18559
+ }
18211
18560
  const directusPool = directusResult.find(({ id }) => id === userRequest.lendingPool.id);
18212
18561
  const trancheName = trancheNames[userRequest.lendingPool.tranches.length - 1][parseInt(userRequest.tranche.orderId)];
18213
18562
  const events = [];
@@ -18303,9 +18652,7 @@ class UserLending {
18303
18652
  : 'Withdrawal',
18304
18653
  trancheName: trancheName,
18305
18654
  trancheId: userRequest.tranche.id,
18306
- requestedAmount: parseUnits(userRequest.tranche.shares).isZero()
18307
- ? userRequest.amountRequested
18308
- : this.convertSharesToAssets(userRequest.amountRequested, userRequest.tranche.balance, userRequest.tranche.shares).toString(),
18655
+ requestedAmount: this.requestedAmountInAssets(userRequest),
18309
18656
  acceptedAmount: userRequest.amountAccepted,
18310
18657
  rejectedAmount: userRequest.amountRejected,
18311
18658
  status: userRequest.status,
@@ -18338,8 +18685,11 @@ class UserLending {
18338
18685
  for (const userFTD of currentFtdBalance.userLendingPoolTrancheFixedTermDepositLocks) {
18339
18686
  const ftdID = parseFloat(userFTD.lendingPoolTrancheFixedTermConfig.configId);
18340
18687
  const trancheID = userFTD.lendingPoolTrancheFixedTermConfig.lendingPoolTranche.id.toLowerCase();
18341
- const totalSupply = userFTD.lendingPool.tranches.reduce((total, cur) => total.add(parseEther(cur.shares)), BigNumber.from(0));
18342
- const amount = this.convertSharesToAssets(userFTD.trancheShares, userFTD.lendingPool.balance, formatEther(totalSupply));
18688
+ // The lock holds shares of ONE tranche, so they are worth that
18689
+ // tranche's share price — not the pool's average across tranches,
18690
+ // which differs whenever the tranches have earned differently.
18691
+ const lockTranche = userFTD.lendingPoolTrancheFixedTermConfig.lendingPoolTranche;
18692
+ const amount = this.convertSharesToAssets(userFTD.trancheShares, lockTranche.balance, lockTranche.shares);
18343
18693
  const item = (_a = trancheMap.get(trancheID)) !== null && _a !== void 0 ? _a : [];
18344
18694
  if (item[ftdID]) {
18345
18695
  item[ftdID] += parseFloat(amount);
@@ -18354,25 +18704,40 @@ class UserLending {
18354
18704
  }
18355
18705
  getCurrentEpochFtdAmount(poolIds, userId, currentEpoch) {
18356
18706
  return __awaiter(this, void 0, void 0, function* () {
18707
+ var _a, _b;
18357
18708
  const currentEpochFtdAmountRes = yield this._graph.request(currentEpochFtdAmountQuery, {
18358
18709
  userId: userId.toLowerCase(),
18359
18710
  poolIds: poolIds.map((id) => id.toLowerCase()),
18360
18711
  currentEpoch: parseFloat(currentEpoch),
18361
18712
  });
18362
- const currentEpochFtdAmounts = new Map();
18713
+ // Deposit requests only (the query filters on type): a deposit's
18714
+ // `amountRequested` is already an ASSET amount, so it is summed as it
18715
+ // is — never put through a share price. Summed, not assigned: a
18716
+ // cancelled request and its replacement share a tranche and a config
18717
+ // in one epoch, and the cancelled one's 0 must not overwrite the live
18718
+ // amount.
18719
+ const totals = new Map();
18363
18720
  for (const userRequest of currentEpochFtdAmountRes.userRequests) {
18364
18721
  const ftdID = parseFloat(userRequest.fixedTermConfigId);
18365
- const item = currentEpochFtdAmounts.get(userRequest.tranche.id);
18366
- const amountRequested = this.convertSharesToAssets(userRequest.amountRequested, userRequest.tranche.balance, userRequest.tranche.shares);
18367
- if (item) {
18368
- const clonedItem = [...item];
18369
- clonedItem[ftdID] = amountRequested;
18370
- currentEpochFtdAmounts.set(userRequest.tranche.id, clonedItem);
18722
+ if (!Number.isInteger(ftdID) || ftdID < 0)
18371
18723
  continue;
18372
- }
18724
+ const perConfig = (_a = totals.get(userRequest.tranche.id)) !== null && _a !== void 0 ? _a : new Map();
18725
+ perConfig.set(ftdID, ((_b = perConfig.get(ftdID)) !== null && _b !== void 0 ? _b : BigNumber.from(0)).add(parseUnits(userRequest.amountRequested)));
18726
+ totals.set(userRequest.tranche.id, perConfig);
18727
+ }
18728
+ // A slot whose total is zero is left out — `'0.0'` is a truthy
18729
+ // string, and a caller testing the slot would read it as an amount.
18730
+ // A tranche with no non-zero slot is left out entirely.
18731
+ const currentEpochFtdAmounts = new Map();
18732
+ for (const [trancheId, perConfig] of totals) {
18373
18733
  const ftdAmounts = [];
18374
- ftdAmounts[ftdID] = amountRequested;
18375
- currentEpochFtdAmounts.set(userRequest.tranche.id, ftdAmounts);
18734
+ for (const [ftdID, total] of perConfig) {
18735
+ if (total.gt(0))
18736
+ ftdAmounts[ftdID] = formatUnits(total);
18737
+ }
18738
+ if (ftdAmounts.length) {
18739
+ currentEpochFtdAmounts.set(trancheId, ftdAmounts);
18740
+ }
18376
18741
  }
18377
18742
  return currentEpochFtdAmounts;
18378
18743
  });
@@ -18393,6 +18758,31 @@ class UserLending {
18393
18758
  return amountMap;
18394
18759
  });
18395
18760
  }
18761
+ /**
18762
+ * A request's outstanding amount in ASSETS (the deployment's stable token).
18763
+ *
18764
+ * The subgraph's `UserRequest.amountRequested` is denominated by request
18765
+ * type. A DEPOSIT request holds assets: the deposit NFT's `assetAmount`,
18766
+ * top-ups added, accepted and rejected amounts taken off. A WITHDRAWAL
18767
+ * request holds tranche SHARES: the withdrawal NFT's `sharesAmount`,
18768
+ * accepted shares taken off. So only a withdrawal is converted, at the
18769
+ * tranche's current share price; a deposit passes through unchanged —
18770
+ * pricing it as shares overstated it by the share price.
18771
+ */
18772
+ requestedAmountInAssets(userRequest) {
18773
+ switch (userRequest.type) {
18774
+ case 'DepositRequest':
18775
+ return userRequest.amountRequested;
18776
+ case 'WithdrawalRequest':
18777
+ return this.convertSharesToAssets(userRequest.amountRequested, userRequest.tranche.balance, userRequest.tranche.shares);
18778
+ default: {
18779
+ // Fail closed: a type this SDK does not know has no known
18780
+ // unit, and pricing it either way would print a wrong figure.
18781
+ const unknownType = userRequest.type;
18782
+ throw new Error(`${UNKNOWN_REQUEST_TYPE_MESSAGE}: ${unknownType}`);
18783
+ }
18784
+ }
18785
+ }
18396
18786
  convertSharesToAssets(sharesAmount, totalAssets, totalSupply) {
18397
18787
  if (parseUnits(totalSupply).isZero())
18398
18788
  return '0';
@@ -25646,9 +26036,9 @@ class SponsoredCallInputError extends Error {
25646
26036
  Object.setPrototypeOf(this, SponsoredCallInputError.prototype);
25647
26037
  }
25648
26038
  }
25649
- const ADDRESS_RE$2 = /^0x[0-9a-fA-F]{40}$/;
26039
+ const ADDRESS_RE$3 = /^0x[0-9a-fA-F]{40}$/;
25650
26040
  function assertAddress(value, code) {
25651
- if (typeof value !== 'string' || !ADDRESS_RE$2.test(value)) {
26041
+ if (typeof value !== 'string' || !ADDRESS_RE$3.test(value)) {
25652
26042
  throw new SponsoredCallInputError(code);
25653
26043
  }
25654
26044
  }
@@ -25777,7 +26167,7 @@ function encodeStableTransfer(input) {
25777
26167
  };
25778
26168
  }
25779
26169
 
25780
- const ADDRESS_RE$1 = /^0x[0-9a-fA-F]{40}$/;
26170
+ const ADDRESS_RE$2 = /^0x[0-9a-fA-F]{40}$/;
25781
26171
  /**
25782
26172
  * Encoded, ready-to-sponsor `LendingPoolManager` calls — read, then encode,
25783
26173
  * NEVER send. Each returns `{ kind, call }`: post `kind` and `[call]` to a
@@ -25814,13 +26204,13 @@ class CallsFacade {
25814
26204
  requestWithdrawal(params) {
25815
26205
  return __awaiter(this, void 0, void 0, function* () {
25816
26206
  const { poolId, trancheId, amount, userAddress } = params;
25817
- if (typeof userAddress !== 'string' || !ADDRESS_RE$1.test(userAddress)) {
26207
+ if (typeof userAddress !== 'string' || !ADDRESS_RE$2.test(userAddress)) {
25818
26208
  throw new SponsoredCallInputError('user');
25819
26209
  }
25820
- if (typeof poolId !== 'string' || !ADDRESS_RE$1.test(poolId)) {
26210
+ if (typeof poolId !== 'string' || !ADDRESS_RE$2.test(poolId)) {
25821
26211
  throw new SponsoredCallInputError('pool');
25822
26212
  }
25823
- if (typeof trancheId !== 'string' || !ADDRESS_RE$1.test(trancheId)) {
26213
+ if (typeof trancheId !== 'string' || !ADDRESS_RE$2.test(trancheId)) {
25824
26214
  throw new SponsoredCallInputError('tranche');
25825
26215
  }
25826
26216
  let shares;
@@ -26472,7 +26862,7 @@ const BEFORE_EXECUTION = ENTRY_POINT_EVENTS.getEventTopic('BeforeExecution');
26472
26862
  const DEPOSIT_REQUESTED = PENDING_POOL_EVENTS.getEventTopic('DepositRequested');
26473
26863
  const ERC20$1 = IERC20MetadataAbi__factory.createInterface();
26474
26864
  const LENDING_POOL_MANAGER$1 = ILendingPoolManagerAbi__factory.createInterface();
26475
- const ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
26865
+ const ADDRESS_RE$1 = /^0x[0-9a-fA-F]{40}$/;
26476
26866
  /**
26477
26867
  * Case-insensitive address equality; `false` for anything that is not a
26478
26868
  * 20-byte hex address. Checksums are not enforced — an all-lowercase address
@@ -26481,8 +26871,8 @@ const ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
26481
26871
  function sameAddress(a, b) {
26482
26872
  return (typeof a === 'string' &&
26483
26873
  typeof b === 'string' &&
26484
- ADDRESS_RE.test(a) &&
26485
- ADDRESS_RE.test(b) &&
26874
+ ADDRESS_RE$1.test(a) &&
26875
+ ADDRESS_RE$1.test(b) &&
26486
26876
  a.toLowerCase() === b.toLowerCase());
26487
26877
  }
26488
26878
  function isHexData(value) {
@@ -26508,7 +26898,7 @@ function isCallShape(call) {
26508
26898
  if (call === null || typeof call !== 'object')
26509
26899
  return false;
26510
26900
  const { to, data } = call;
26511
- return typeof to === 'string' && ADDRESS_RE.test(to) && isHexData(data);
26901
+ return typeof to === 'string' && ADDRESS_RE$1.test(to) && isHexData(data);
26512
26902
  }
26513
26903
  function isZeroValue(value) {
26514
26904
  if (value === undefined)
@@ -29137,6 +29527,26 @@ class StrategiesFacade {
29137
29527
  return yield this._dataService.getPoolTvlHistory(poolId, options);
29138
29528
  });
29139
29529
  }
29530
+ /**
29531
+ * `getPoolTvlHistory` plus `opening` — the newest clearing before the
29532
+ * window, read at its own block like every other point, or `null` when
29533
+ * the pool has none — from the same read. Pass the result to
29534
+ * `combineTvlHistories` as a leg with its `usdRate`: the opening is what
29535
+ * the leg held before its first point, so a window cut at a different
29536
+ * time on another chain does not count it 0. Same options and errors as
29537
+ * `getPoolTvlHistory`; the extra cost is one clearing row (or, for
29538
+ * `fromEpoch`, one small request) and one block.
29539
+ *
29540
+ * ```ts
29541
+ * const leg = await kasu.strategies.getPoolTvlHistoryWindow(poolId, { count: 52 });
29542
+ * // { entries: PoolTvlHistoryEntry[], opening: PoolTvlHistoryEntry | null }
29543
+ * ```
29544
+ */
29545
+ getPoolTvlHistoryWindow(poolId_1) {
29546
+ return __awaiter(this, arguments, void 0, function* (poolId, options = {}) {
29547
+ return yield this._dataService.getPoolTvlHistoryWindow(poolId, options);
29548
+ });
29549
+ }
29140
29550
  /**
29141
29551
  * Fetch a single strategy by pool ID. Returns `null` if not found.
29142
29552
  */
@@ -29461,17 +29871,24 @@ function cancelDeadline(request, nextEpochStart, nowSeconds) {
29461
29871
  const isCancelled = (events) => events.some((e) => e.requestType === 'Cancelled');
29462
29872
  const isForced = (events) => events.some((e) => e.requestType === 'Forced');
29463
29873
  const initiatedEvent = (events) => events.find((e) => e.requestType === 'Initiated');
29464
- /**
29465
- * Subgraph behaviour: when a request is cancelled, the on-request
29466
- * `requestedAmount` field is reset to 0 (the lender's effective balance is
29467
- * restored). The original amount survives on the `Initiated` event's
29468
- * `assetAmount`. Recover from there so cancelled rows still carry the amount
29469
- * the lender originally asked for.
29470
- */
29874
+ /** `assetAmount` of the `Initiated` event, or 0 when there is none. */
29471
29875
  const initiatedAmountOf = (events) => {
29472
29876
  const initiated = initiatedEvent(events);
29473
29877
  return initiated ? Number(initiated.assetAmount || '0') : 0;
29474
29878
  };
29879
+ /**
29880
+ * Subgraph behaviour: when a request is cancelled, the on-request
29881
+ * `requestedAmount` field is reset to 0 (the lender's effective balance is
29882
+ * restored). The amount cancelled survives on the `Cancelled` event's
29883
+ * `assetAmount` — everything still outstanding at the cancel, top-ups
29884
+ * included. Only when that event carries no figure does this fall back to the
29885
+ * `Initiated` event, which holds the FIRST submission alone and so misses
29886
+ * every top-up.
29887
+ */
29888
+ const cancelledAmountOf = (events) => {
29889
+ const cancelledEvent = events.find((e) => e.requestType === 'Cancelled');
29890
+ return num(cancelledEvent === null || cancelledEvent === void 0 ? void 0 : cancelledEvent.assetAmount) || initiatedAmountOf(events);
29891
+ };
29475
29892
  /**
29476
29893
  * A deposit is REALLOCATED when the timeline carries a `Reallocated` event, or
29477
29894
  * an `Accepted` event into a tranche other than the one requested.
@@ -29496,17 +29913,15 @@ const numOrNull = (str) => {
29496
29913
  * Convert a `UserRequest` into a `RequestState`. Pure — no clock, no network,
29497
29914
  * no copy.
29498
29915
  *
29499
- * BRANCH ORDER (this IS the behaviour; it reproduces kasu-ui's
29500
- * `deriveTransactionView` check for check):
29916
+ * BRANCH ORDER (this IS the behaviour):
29501
29917
  *
29502
29918
  * 1. a `Cancelled` event → `cancelled`, neutral, 0
29503
29919
  * 2. a withdrawal with a `Forced` event → `forced`, outflow, −accepted
29504
29920
  * 3. a reallocated deposit → `reallocated`, inflow, +accepted
29505
- * 4. a withdrawal partly filled with a LIVE
29506
- * remainder (cycle still open) → `partial`, outflow, −accepted
29921
+ * 4. a withdrawal partly filled (paid > 0) with
29922
+ * a LIVE remainder (queued > 0, cycle open) → `partial`, outflow, −accepted
29507
29923
  * 5. resolved (`status === 'Processed'`):
29508
- * withdrawal, partly filled → `partial`, outflow, −accepted
29509
- * withdrawal, fully filled → `complete`, outflow, −accepted
29924
+ * withdrawal (nothing left queued) → `complete`, outflow, −accepted
29510
29925
  * deposit, nothing accepted → `rejected`, neutral, 0
29511
29926
  * deposit, part rejected → `partial`, inflow, +accepted
29512
29927
  * deposit, fully accepted → `complete`, inflow, +accepted
@@ -29534,10 +29949,10 @@ function deriveRequestState(request) {
29534
29949
  const isWithdrawal = request.requestType === 'Withdrawal';
29535
29950
  const cancelled = isCancelled(request.events);
29536
29951
  // Cancelled requests have `requestedAmount` zeroed on the request itself;
29537
- // pull the original value from the Initiated event so the row still
29538
- // carries "100 cancelled" instead of "0 cancelled".
29952
+ // take the amount from the Cancelled event so the row still carries
29953
+ // "1500 cancelled" (1000 + a 500 top-up) instead of "0 cancelled".
29539
29954
  const requested = cancelled
29540
- ? num(request.requestedAmount) || initiatedAmountOf(request.events)
29955
+ ? num(request.requestedAmount) || cancelledAmountOf(request.events)
29541
29956
  : num(request.requestedAmount);
29542
29957
  const accepted = num(request.acceptedAmount);
29543
29958
  const rejected = num(request.rejectedAmount);
@@ -29588,18 +30003,23 @@ function deriveRequestState(request) {
29588
30003
  }
29589
30004
  // 4. Withdrawal partly filled with a LIVE remainder: the request returns
29590
30005
  // to the queue with a live Cancel. Checked BEFORE the resolved branch and
29591
- // via `isCycleClosed`, never via the sticky raw status.
30006
+ // via `isCycleClosed`, never via the sticky raw status. `requested` is
30007
+ // what is still OUTSTANDING, so "partly filled" is "something paid AND
30008
+ // something still queued" — never a comparison of the two, which would
30009
+ // turn on whether more was paid than is left.
29592
30010
  if (isWithdrawal &&
29593
30011
  accepted > 0 &&
29594
- accepted < requested &&
30012
+ requested > 0 &&
29595
30013
  !isCycleClosed(request)) {
29596
30014
  return Object.assign(Object.assign({}, base), { kind: 'outflow', amount: -accepted, statusCode: 'partial' });
29597
30015
  }
29598
30016
  // 5. Resolved — a rejection IS a resolution.
29599
30017
  if (request.status === UserRequestStatus.PROCESSED) {
30018
+ // A withdrawal is resolved only once nothing is left queued — a
30019
+ // partly filled one returns to the queue (branch 4), and one cancelled
30020
+ // with a remainder is branch 1 — so a resolved withdrawal is complete.
29600
30021
  if (isWithdrawal) {
29601
- const partly = accepted < requested;
29602
- return Object.assign(Object.assign({}, base), { kind: 'outflow', amount: -accepted, statusCode: partly ? 'partial' : 'complete' });
30022
+ return Object.assign(Object.assign({}, base), { kind: 'outflow', amount: -accepted, statusCode: 'complete' });
29603
30023
  }
29604
30024
  // Deposit: full reject vs partial vs full accept.
29605
30025
  if (accepted === 0) {
@@ -29956,6 +30376,102 @@ function normaliseMapping(mapping) {
29956
30376
  return out;
29957
30377
  }
29958
30378
 
30379
+ /** What `strategyDeployments` throws for an id it cannot place. */
30380
+ class StrategyDeploymentInputError extends Error {
30381
+ constructor(code) {
30382
+ super(`strategyDeployments: input refused (${code})`);
30383
+ this.name = 'StrategyDeploymentInputError';
30384
+ this.code = code;
30385
+ Object.setPrototypeOf(this, StrategyDeploymentInputError.prototype);
30386
+ }
30387
+ }
30388
+ /** The canonical deployment: its pool ids ARE the strategies' ids. */
30389
+ const CANONICAL_CHAIN = 'base';
30390
+ const ADDRESS_RE = /^0x[0-9a-f]{40}$/;
30391
+ /** The deployment's mapping with both sides lowercased; Base never has one. */
30392
+ function mappingOf(configs, chain) {
30393
+ var _a;
30394
+ if (chain === CANONICAL_CHAIN)
30395
+ return [];
30396
+ return Object.entries((_a = configs[chain].poolMetadataMapping) !== null && _a !== void 0 ? _a : {}).map(([local, canonical]) => [local.toLowerCase(), canonical.toLowerCase()]);
30397
+ }
30398
+ /**
30399
+ * `strategyDeployments` over any configs — the export reads `CHAIN_CONFIGS`;
30400
+ * the spec passes its own to cover shapes the built-in mapping lacks.
30401
+ */
30402
+ function resolveStrategyDeployments(configs, poolId, chain) {
30403
+ const id = typeof poolId === 'string' ? poolId.trim().toLowerCase() : '';
30404
+ if (!ADDRESS_RE.test(id)) {
30405
+ throw new StrategyDeploymentInputError('pool-id');
30406
+ }
30407
+ if (typeof chain !== 'string' ||
30408
+ !Object.prototype.hasOwnProperty.call(configs, chain)) {
30409
+ throw new StrategyDeploymentInputError('chain');
30410
+ }
30411
+ const chains = Object.keys(configs);
30412
+ const mappings = chains.map((c) => [c, mappingOf(configs, c)]);
30413
+ const isLocalElsewhere = mappings.some(([c, mapping]) => c !== chain && mapping.some(([local]) => local === id));
30414
+ let canonical;
30415
+ if (chain === CANONICAL_CHAIN) {
30416
+ // A Base id is its own Base pool — unless the mapping says it is
30417
+ // another deployment's chain-local id, which names no Base pool.
30418
+ if (isLocalElsewhere) {
30419
+ throw new StrategyDeploymentInputError('wrong-chain');
30420
+ }
30421
+ canonical = id;
30422
+ }
30423
+ else {
30424
+ const own = mappingOf(configs, chain).find(([local]) => local === id);
30425
+ if (own) {
30426
+ canonical = own[1];
30427
+ }
30428
+ else {
30429
+ const isCanonical = mappings.some(([, mapping]) => mapping.some(([, target]) => target === id));
30430
+ if (isLocalElsewhere || isCanonical) {
30431
+ throw new StrategyDeploymentInputError('wrong-chain');
30432
+ }
30433
+ // Unmapped off Base: a strategy of one on its own chain (every
30434
+ // XDC USDC pool today). Claiming a Base counterpart would read
30435
+ // Base with an XDC address.
30436
+ return [{ chain, poolId: id }];
30437
+ }
30438
+ }
30439
+ const found = [
30440
+ { chain: CANONICAL_CHAIN, poolId: canonical },
30441
+ ];
30442
+ for (const [c, mapping] of mappings) {
30443
+ for (const [local, target] of mapping) {
30444
+ if (target === canonical)
30445
+ found.push({ chain: c, poolId: local });
30446
+ }
30447
+ }
30448
+ return found;
30449
+ }
30450
+ /**
30451
+ * Every deployment a strategy has a pool on, canonical (Base) first, then the
30452
+ * others in `CHAIN_CONFIGS` order — the legs to fetch and pass to
30453
+ * `combineTvlHistories`. One entry for a strategy that lives on one chain
30454
+ * only (PayFi, on Base).
30455
+ *
30456
+ * `chain` is the deployment `poolId` was read on — required, because an
30457
+ * address alone does not say which chain it belongs to. From either side of
30458
+ * a mapping the answer is the same set: Tax Pay's Base id on `'base'` and
30459
+ * its XDC id on `'xdc'` both return both pools. An id the mapping does not
30460
+ * know is a strategy of one on its own chain. Ids are compared
30461
+ * case-insensitively and returned lowercase.
30462
+ *
30463
+ * Throws `StrategyDeploymentInputError` for a malformed id, an unknown chain,
30464
+ * or an id the mapping places on another deployment (`'wrong-chain'`).
30465
+ *
30466
+ * ```ts
30467
+ * strategyDeployments(strategy.id, 'base');
30468
+ * // [{ chain: 'base', poolId: '0x…' }, { chain: 'xdc', poolId: '0x…' }]
30469
+ * ```
30470
+ */
30471
+ function strategyDeployments(poolId, chain) {
30472
+ return resolveStrategyDeployments(CHAIN_CONFIGS, poolId, chain);
30473
+ }
30474
+
29959
30475
  /** Directus instance holding Kasu's pool editorial content. */
29960
30476
  const DEFAULT_DIRECTUS_URL = 'https://kasu-finance.directus.app/';
29961
30477
  /**
@@ -30608,4 +31124,4 @@ function weightedAverageApy(slices) {
30608
31124
  return weighted / totalBalance;
30609
31125
  }
30610
31126
 
30611
- export { APXIUM, AU_ALPHA3, AU_MIN_CUMULATIVE_BY_STABLE, BatchPendingError, BatchRevertedError, BatchSubmissionError, CHAIN_CONFIGS, CLEARING_WINDOW_SECONDS, CONTRACT_TTL_MS, CallsFacade, DAYS_PER_EPOCH, DAYS_PER_MONTH, DEFAULT_BATCH_POLLING_POLICY, DepositBatchMismatchError, DepositFlow, DepositsFacade, ENTRY_POINT_V07, EPOCHS_IN_YEAR, Flow, FlowStore, FlowsFacade, INVALID_ACCEPTANCE_SIGNATURE_MESSAGE, INVALID_AUTH_SIGNATURE_MESSAGE, INVOICEMATE, Kasu, KasuSdk, MAX_LENDING_AMOUNT_FALLBACK, MIN_DAYS_FOR_MONTHS, MIN_LENDING_AMOUNT_FALLBACK, MIN_TRANCHE_CAPACITY, NOT_A_WITHDRAWAL_CALL_MESSAGE, NO_DIRECTUS_URL_MESSAGE, NO_HISTORY_PROVIDER_MESSAGE, NO_KYC_PARAMS_MESSAGE, NO_SPENDER_MESSAGE, NO_WITHDRAWAL_ENCODER_MESSAGE, PastStateUnavailableError, PoolTvlHistoryAbortedError, PoolTvlHistoryTimeoutError, PortfolioFacade, READ_ONLY_MESSAGE, RIXON_CAPITAL, SECONDS_PER_WEEK, SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, SdkConfig, SponsoredCallInputError, StrategiesFacade, UPPER_MEZZANINE, WithdrawFlow, accruedInterest, aggregateYieldHistory, apyToEpochRate, asContractType, auMinimumRemaining, auThresholdFor, availableFixedTermConfigs, batchOutcomeOf, buildContractVersionType, buildFullNameRequestMessage, buildLegacyContractRequestMessage, buildLoanAgreementSignMessage, cancelDeadline, ceilToCents, checkBatchOutcome, checkSponsoredCallOutcome, classifyWalletFailure, compareTrancheSeniority, computeSettlementWindow, countSubmissions, dailyInterest, decodeRevert, deriveCycleDates, derivePoolStatus, deriveRequestState, encodeCancelDepositCall, encodeCancelWithdrawalCall, encodeDepositData, encodeRequestWithdrawalCall, encodeStableTransfer, encodeWithdrawAtExpiryCall, epochRateToApy, epochTrancheYield, explorerAddressUrl, explorerTxUrl, extractRevertData, fetchUnusedPoolIds, firstSubmissionTimestamp, floorToCents, formatSignTimestampUtc, getCreditOriginator, getInstitutionalLender, getStrategyRegion, getTrancheDisplayName, isAuMinimumExempt, isAustralianKyc, isBelowMinimumCapacity, isCycleClosed, isDefinitivelyNotSubmitted, isFixedTermConfigId, isUnpredictableGas, isUserRejected, lastEventTimestamp, lockDurationDays, lockDurationMonths, maxNetRateCeiling, netEffectiveApy, netTrancheApyBounds, nextCycleBoundary, parseFormattedMessage, parseMinorUnits, parseTrancheBound, pickDefaultTrancheId, pickHighestYieldTranche, pickShortDescription, poolAllTranchesFull, poolMaxApy, poolTvl, projectedAnnualEarnings, proveDepositInReceipt, proveUserOperationInReceipt, resolveBoundShortcuts, resolveDepositBounds, selectVisiblePools, submissionEvents, submitBatch, submitSponsoredCall, trancheApyBounds, trancheHasCapacity, trancheRiskRank, validateDepositBatchCalls, weeklyInterest, weightedAverageApy };
31127
+ export { APXIUM, AU_ALPHA3, AU_MIN_CUMULATIVE_BY_STABLE, BatchPendingError, BatchRevertedError, BatchSubmissionError, CHAIN_CONFIGS, CLEARING_WINDOW_SECONDS, CONTRACT_TTL_MS, CallsFacade, DAYS_PER_EPOCH, DAYS_PER_MONTH, DEFAULT_BATCH_POLLING_POLICY, DepositBatchMismatchError, DepositFlow, DepositsFacade, ENTRY_POINT_V07, EPOCHS_IN_YEAR, Flow, FlowStore, FlowsFacade, INVALID_ACCEPTANCE_SIGNATURE_MESSAGE, INVALID_AUTH_SIGNATURE_MESSAGE, INVOICEMATE, Kasu, KasuSdk, MAX_LENDING_AMOUNT_FALLBACK, MIN_DAYS_FOR_MONTHS, MIN_LENDING_AMOUNT_FALLBACK, MIN_TRANCHE_CAPACITY, NOT_A_WITHDRAWAL_CALL_MESSAGE, NO_DIRECTUS_URL_MESSAGE, NO_HISTORY_PROVIDER_MESSAGE, NO_KYC_PARAMS_MESSAGE, NO_SPENDER_MESSAGE, NO_WITHDRAWAL_ENCODER_MESSAGE, PastStateUnavailableError, PoolTvlHistoryAbortedError, PoolTvlHistoryTimeoutError, PortfolioFacade, READ_ONLY_MESSAGE, RIXON_CAPITAL, SECONDS_PER_WEEK, SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, SdkConfig, SponsoredCallInputError, StrategiesFacade, StrategyDeploymentInputError, TvlHistoryInputError, UPPER_MEZZANINE, WithdrawFlow, accruedInterest, aggregateYieldHistory, apyToEpochRate, asContractType, auMinimumRemaining, auThresholdFor, availableFixedTermConfigs, batchOutcomeOf, buildContractVersionType, buildFullNameRequestMessage, buildLegacyContractRequestMessage, buildLoanAgreementSignMessage, cancelDeadline, ceilToCents, checkBatchOutcome, checkSponsoredCallOutcome, classifyWalletFailure, combineTvlHistories, compareTrancheSeniority, computeSettlementWindow, countSubmissions, dailyInterest, decodeRevert, deriveCycleDates, derivePoolStatus, deriveRequestState, encodeCancelDepositCall, encodeCancelWithdrawalCall, encodeDepositData, encodeRequestWithdrawalCall, encodeStableTransfer, encodeWithdrawAtExpiryCall, epochRateToApy, epochTrancheYield, explorerAddressUrl, explorerTxUrl, extractRevertData, fetchUnusedPoolIds, firstSubmissionTimestamp, floorToCents, formatSignTimestampUtc, getCreditOriginator, getInstitutionalLender, getStrategyRegion, getTrancheDisplayName, isAuMinimumExempt, isAustralianKyc, isBelowMinimumCapacity, isCycleClosed, isDefinitivelyNotSubmitted, isFixedTermConfigId, isUnpredictableGas, isUserRejected, lastEventTimestamp, lockDurationDays, lockDurationMonths, maxNetRateCeiling, netEffectiveApy, netTrancheApyBounds, nextCycleBoundary, parseFormattedMessage, parseMinorUnits, parseTrancheBound, pickDefaultTrancheId, pickHighestYieldTranche, pickShortDescription, poolAllTranchesFull, poolMaxApy, poolTvl, projectedAnnualEarnings, proveDepositInReceipt, proveUserOperationInReceipt, resolveBoundShortcuts, resolveDepositBounds, selectVisiblePools, strategyDeployments, submissionEvents, submitBatch, submitSponsoredCall, trancheApyBounds, trancheHasCapacity, trancheRiskRank, validateDepositBatchCalls, weeklyInterest, weightedAverageApy };