@kasufinance/kasu-sdk 2.5.0 → 2.7.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 (128) hide show
  1. package/README.md +144 -7
  2. package/dist/bundle.cjs.js +1667 -21
  3. package/dist/bundle.esm.js +1630 -22
  4. package/dist/domain/au-minimum.d.ts +135 -0
  5. package/dist/domain/au-minimum.js +154 -0
  6. package/dist/domain/au-minimum.js.map +1 -0
  7. package/dist/domain/index.d.ts +18 -3
  8. package/dist/domain/index.js +13 -3
  9. package/dist/domain/index.js.map +1 -1
  10. package/dist/domain/loan-contract.d.ts +174 -0
  11. package/dist/domain/loan-contract.js +160 -0
  12. package/dist/domain/loan-contract.js.map +1 -0
  13. package/dist/domain/requests.d.ts +219 -0
  14. package/dist/domain/requests.js +218 -0
  15. package/dist/domain/requests.js.map +1 -0
  16. package/dist/domain/settlement.d.ts +97 -0
  17. package/dist/domain/settlement.js +117 -0
  18. package/dist/domain/settlement.js.map +1 -0
  19. package/dist/domain/wallet-errors.d.ts +92 -0
  20. package/dist/domain/wallet-errors.js +155 -0
  21. package/dist/domain/wallet-errors.js.map +1 -0
  22. package/dist/facade/chain-configs.js +7 -1
  23. package/dist/facade/chain-configs.js.map +1 -1
  24. package/dist/facade/deposits.js +2 -1
  25. package/dist/facade/deposits.js.map +1 -1
  26. package/dist/facade/flows.d.ts +95 -0
  27. package/dist/facade/flows.js +116 -0
  28. package/dist/facade/flows.js.map +1 -0
  29. package/dist/facade/index.d.ts +3 -0
  30. package/dist/facade/index.js +3 -0
  31. package/dist/facade/index.js.map +1 -1
  32. package/dist/facade/kasu.d.ts +6 -2
  33. package/dist/facade/kasu.js +28 -3
  34. package/dist/facade/kasu.js.map +1 -1
  35. package/dist/facade/read-only.d.ts +12 -0
  36. package/dist/facade/read-only.js +13 -0
  37. package/dist/facade/read-only.js.map +1 -0
  38. package/dist/facade/user-portfolio.d.ts +18 -0
  39. package/dist/facade/user-portfolio.js +23 -0
  40. package/dist/facade/user-portfolio.js.map +1 -1
  41. package/dist/flows/deposit-flow.d.ts +301 -0
  42. package/dist/flows/deposit-flow.js +358 -0
  43. package/dist/flows/deposit-flow.js.map +1 -0
  44. package/dist/flows/flow.d.ts +72 -0
  45. package/dist/flows/flow.js +110 -0
  46. package/dist/flows/flow.js.map +1 -0
  47. package/dist/flows/index.d.ts +19 -0
  48. package/dist/flows/index.js +17 -0
  49. package/dist/flows/index.js.map +1 -0
  50. package/dist/flows/observable.d.ts +59 -0
  51. package/dist/flows/observable.js +81 -0
  52. package/dist/flows/observable.js.map +1 -0
  53. package/dist/flows/withdraw-flow.d.ts +99 -0
  54. package/dist/flows/withdraw-flow.js +83 -0
  55. package/dist/flows/withdraw-flow.js.map +1 -0
  56. package/dist/index.d.ts +2 -0
  57. package/dist/index.js +7 -0
  58. package/dist/index.js.map +1 -1
  59. package/dist/services/DataService/data-service.js +3 -11
  60. package/dist/services/DataService/data-service.js.map +1 -1
  61. package/dist/services/DataService/directus-client.d.ts +26 -0
  62. package/dist/services/DataService/directus-client.js +38 -0
  63. package/dist/services/DataService/directus-client.js.map +1 -0
  64. package/dist/services/UserLending/user-lending.js +11 -7
  65. package/dist/services/UserLending/user-lending.js.map +1 -1
  66. package/package.json +8 -2
  67. package/src/domain/au-minimum.ts +192 -0
  68. package/src/domain/index.ts +73 -3
  69. package/src/domain/loan-contract.ts +275 -0
  70. package/src/domain/requests.ts +467 -0
  71. package/src/domain/settlement.ts +161 -0
  72. package/src/domain/wallet-errors.ts +173 -0
  73. package/src/facade/chain-configs.ts +7 -1
  74. package/src/facade/deposits.ts +2 -3
  75. package/src/facade/flows.ts +172 -0
  76. package/src/facade/index.ts +8 -0
  77. package/src/facade/kasu.ts +43 -3
  78. package/src/facade/read-only.ts +13 -0
  79. package/src/facade/user-portfolio.ts +24 -0
  80. package/src/flows/deposit-flow.ts +775 -0
  81. package/src/flows/flow.ts +108 -0
  82. package/src/flows/index.ts +45 -0
  83. package/src/flows/observable.ts +97 -0
  84. package/src/flows/withdraw-flow.ts +210 -0
  85. package/src/index.ts +9 -0
  86. package/src/services/DataService/data-service.ts +7 -25
  87. package/src/services/DataService/directus-client.ts +54 -0
  88. package/src/services/UserLending/user-lending.ts +17 -21
  89. package/dist/domain/deposit-bounds.test.d.ts +0 -1
  90. package/dist/domain/deposit-bounds.test.js +0 -135
  91. package/dist/domain/deposit-bounds.test.js.map +0 -1
  92. package/dist/domain/partners.test.d.ts +0 -1
  93. package/dist/domain/partners.test.js +0 -53
  94. package/dist/domain/partners.test.js.map +0 -1
  95. package/dist/domain/pools.test.d.ts +0 -1
  96. package/dist/domain/pools.test.js +0 -184
  97. package/dist/domain/pools.test.js.map +0 -1
  98. package/dist/domain/rates.test.d.ts +0 -1
  99. package/dist/domain/rates.test.js +0 -181
  100. package/dist/domain/rates.test.js.map +0 -1
  101. package/dist/domain/tranche-display-name.test.d.ts +0 -1
  102. package/dist/domain/tranche-display-name.test.js +0 -58
  103. package/dist/domain/tranche-display-name.test.js.map +0 -1
  104. package/dist/domain/tranches.test.d.ts +0 -1
  105. package/dist/domain/tranches.test.js +0 -206
  106. package/dist/domain/tranches.test.js.map +0 -1
  107. package/dist/facade/config.test.d.ts +0 -1
  108. package/dist/facade/config.test.js +0 -216
  109. package/dist/facade/config.test.js.map +0 -1
  110. package/dist/facade/facade.test.d.ts +0 -1
  111. package/dist/facade/facade.test.js +0 -201
  112. package/dist/facade/facade.test.js.map +0 -1
  113. package/dist/services/Locking/calculate-apy.test.d.ts +0 -1
  114. package/dist/services/Locking/calculate-apy.test.js +0 -41
  115. package/dist/services/Locking/calculate-apy.test.js.map +0 -1
  116. package/dist/tests/sample.test.d.ts +0 -1
  117. package/dist/tests/sample.test.js +0 -59
  118. package/dist/tests/sample.test.js.map +0 -1
  119. package/src/domain/deposit-bounds.test.ts +0 -200
  120. package/src/domain/partners.test.ts +0 -83
  121. package/src/domain/pools.test.ts +0 -260
  122. package/src/domain/rates.test.ts +0 -254
  123. package/src/domain/tranche-display-name.test.ts +0 -96
  124. package/src/domain/tranches.test.ts +0 -300
  125. package/src/facade/config.test.ts +0 -265
  126. package/src/facade/facade.test.ts +0 -250
  127. package/src/services/Locking/calculate-apy.test.ts +0 -52
  128. package/src/tests/sample.test.ts +0 -63
@@ -0,0 +1,160 @@
1
+ import { ethers } from 'ethers';
2
+ /** Narrow the backend's loose `contractType` string to the encoded union. */
3
+ export function asContractType(raw) {
4
+ return raw === 'exempt' ? 'exempt' : 'retail';
5
+ }
6
+ /**
7
+ * Parse the server's JSON-string `formattedMessage` into a tree. Returns
8
+ * `null` on parse failure so a renderer can fall back to the plaintext.
9
+ */
10
+ export function parseFormattedMessage(raw) {
11
+ try {
12
+ const parsed = JSON.parse(raw);
13
+ if (parsed && typeof parsed === 'object')
14
+ return parsed;
15
+ return null;
16
+ }
17
+ catch (_a) {
18
+ return null;
19
+ }
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // The on-chain `depositData` blob
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * Pack the contract version and type into the `versionType` word.
26
+ *
27
+ * ```
28
+ * high byte = contract version (>= 1)
29
+ * low byte = 0 for retail, 1 for exempt
30
+ * ```
31
+ */
32
+ export function buildContractVersionType(contractVersion, contractType) {
33
+ return (contractVersion << 8) + (contractType === 'retail' ? 0 : 1);
34
+ }
35
+ /**
36
+ * Build the on-chain `depositData` blob that `requestDepositWithKyc` expects.
37
+ *
38
+ * The KasuController decodes the bytes as
39
+ * `(bytes signature, uint256 timestamp, uint256 versionType)` and uses the
40
+ * embedded acceptance signature to verify — retrospectively, via the
41
+ * agreements service `/contract/resolve` — that the lender signed the
42
+ * loan-contract text. The ABI tuple and the packing are consensus-critical:
43
+ * these bytes go on chain.
44
+ *
45
+ * kasu-ui encodes this with viem, kasu-mobile with ethers v5 (viem is not
46
+ * available on Expo). This is the ethers v5 implementation, and
47
+ * `loan-contract.test.ts` pins its output byte-for-byte against fixtures
48
+ * produced by the viem version, so the two apps can never diverge here.
49
+ *
50
+ * @param args.signature EIP-191 signature from the lender accepting
51
+ * `contractMessage`, as a 0x-prefixed hex string.
52
+ * @param args.timestamp ms-epoch from the contract response.
53
+ */
54
+ export function encodeDepositData(args) {
55
+ const versionType = buildContractVersionType(args.contractVersion, args.contractType);
56
+ return ethers.utils.defaultAbiCoder.encode(['bytes', 'uint256', 'uint256'], [
57
+ args.signature,
58
+ ethers.BigNumber.from(args.timestamp),
59
+ ethers.BigNumber.from(versionType),
60
+ ]);
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // The signed messages
64
+ // ---------------------------------------------------------------------------
65
+ const MONTH_NAMES = [
66
+ 'January',
67
+ 'February',
68
+ 'March',
69
+ 'April',
70
+ 'May',
71
+ 'June',
72
+ 'July',
73
+ 'August',
74
+ 'September',
75
+ 'October',
76
+ 'November',
77
+ 'December',
78
+ ];
79
+ /**
80
+ * Format a unix timestamp as `{day} {MonthName} {yyyy}, {HH}:{mm}` in UTC.
81
+ * Day is non-padded; hour and minute are zero-padded to two digits (24h). A
82
+ * timestamp with >= 13 digits is treated as milliseconds, otherwise as seconds
83
+ * — the same auto-detection kasu-backend applies.
84
+ *
85
+ * Deliberately a manual formatter with English month names: no locale, no
86
+ * `Intl`, so the output is byte-identical across runtimes and time zones. This
87
+ * is not a display date. It goes inside a signed message.
88
+ *
89
+ * e.g. 1785313320000 → `"29 July 2026, 08:22"`
90
+ */
91
+ export function formatSignTimestampUtc(timestamp) {
92
+ const ms = timestamp.toString().length >= 13 ? timestamp : timestamp * 1000;
93
+ const date = new Date(ms);
94
+ const day = date.getUTCDate();
95
+ const month = MONTH_NAMES[date.getUTCMonth()];
96
+ const year = date.getUTCFullYear();
97
+ const hours = String(date.getUTCHours()).padStart(2, '0');
98
+ const minutes = String(date.getUTCMinutes()).padStart(2, '0');
99
+ return `${day} ${month} ${year}, ${hours}:${minutes}`;
100
+ }
101
+ /**
102
+ * The 4-line human-readable message a lender signs to generate their loan
103
+ * agreement for review — `POST /contract/generate`.
104
+ *
105
+ * ⚠️ BYTE-EXACT PROTOCOL STRING. kasu-backend rebuilds this string from the
106
+ * request body and verifies the signature against it, so the wording,
107
+ * ordering, separators, line breaks and date format are all part of the wire
108
+ * contract. The separator between the line-2 fields is a MIDDLE DOT U+00B7
109
+ * (·) with a single space on each side; the four lines are joined with `\n`.
110
+ *
111
+ * The backend takes this format only when all four display fields are present
112
+ * and non-empty, and it cross-checks `amountLabel`'s leading number against
113
+ * the `depositAmount` it was sent (thousands separators stripped) — a message
114
+ * that states an amount other than the one being executed is refused.
115
+ */
116
+ export function buildLoanAgreementSignMessage(p) {
117
+ return [
118
+ 'Generate my Loan Agreement for review:',
119
+ `${p.strategyName} · ${p.region} · ${p.optionName} · ${p.amountLabel}.`,
120
+ `Request made ${formatSignTimestampUtc(p.timestamp)} UTC.`,
121
+ 'This request does not commit me to lend.',
122
+ ].join('\n');
123
+ }
124
+ /**
125
+ * The legacy `/contract/generate` and `/contract/resolve` message.
126
+ *
127
+ * ⚠️ BYTE-EXACT PROTOCOL STRING. kasu-backend rebuilds it as
128
+ * `` `I request contract content for ${address} at ${timestamp}.` `` from the
129
+ * `address` and `timestamp` fields of the request body — so the string signed
130
+ * and the body sent must agree exactly, INCLUDING the address casing. This
131
+ * builder lowercases, and the request body must carry the same lowercased
132
+ * address; that is what both apps signing this format do today.
133
+ *
134
+ * The backend takes this path whenever the four human-readable display fields
135
+ * are absent, and documents it as permanent until the legacy app is
136
+ * decommissioned. `/contract/resolve` has no other format — every consumer
137
+ * signs this one to retrieve an existing agreement.
138
+ *
139
+ * @param timestampMs ms-epoch, and the same value sent as the body's
140
+ * `timestamp`.
141
+ */
142
+ export function buildLegacyContractRequestMessage(address, timestampMs) {
143
+ return `I request contract content for ${address.toLowerCase()} at ${timestampMs}.`;
144
+ }
145
+ /**
146
+ * The `POST /contract/fullname` message.
147
+ *
148
+ * ⚠️ BYTE-EXACT PROTOCOL STRING, on the same terms as
149
+ * `buildLegacyContractRequestMessage`: kasu-backend rebuilds
150
+ * `` `I request my full name for ${address} at ${timestamp}.` `` from the
151
+ * request body and verifies the signature against it, so the body must carry
152
+ * the same lowercased address this builder signs.
153
+ *
154
+ * @param timestampMs ms-epoch, and the same value sent as the body's
155
+ * `timestamp`.
156
+ */
157
+ export function buildFullNameRequestMessage(address, timestampMs) {
158
+ return `I request my full name for ${address.toLowerCase()} at ${timestampMs}.`;
159
+ }
160
+ //# sourceMappingURL=loan-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loan-contract.js","sourceRoot":"","sources":["../../src/domain/loan-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import { UserRequest, UserRequestEvent } from '../services/UserLending/types';
2
+ /**
3
+ * The lending-request view model, as CODES.
4
+ *
5
+ * Lifted verbatim from kasu-ui's `derive-transaction-view.ts` +
6
+ * `request-bundle.ts`, minus every word. kasu-ui's `deriveTransactionView`
7
+ * produces a `TransactionView` that mixes derived FACTS (status code, amounts,
8
+ * kind, ids, submission count, timestamps) with COPY (the status word, the
9
+ * type label, the detail line beneath it, tooltip keys). Only the facts belong
10
+ * in this layer: the copy stays in each application, where the design system,
11
+ * the register and the visitor's language are.
12
+ *
13
+ * The branch ORDER below is the behaviour — cancelled beats forced beats
14
+ * reallocated beats a live withdrawal remainder beats the resolved outcomes
15
+ * beats pending. It reproduces `deriveTransactionView` check for check, so a
16
+ * consumer that renders its own words on top of `statusCode` gets exactly the
17
+ * row kasu-ui has been showing.
18
+ */
19
+ /**
20
+ * Stable status code for filters, tests and the caller's own status word.
21
+ * Independent of any user-facing copy — kasu-ui's four-value vocabulary
22
+ * (Queued / Processing / Completed / Cancelled) is a rendering of these seven
23
+ * codes, not a replacement for them.
24
+ */
25
+ export type RequestStatusCode = 'pending' | 'complete' | 'partial' | 'rejected' | 'reallocated' | 'cancelled' | 'forced';
26
+ /**
27
+ * Direction of value flow into / out of the lender's balance. `neutral`
28
+ * applies when the request was cancelled or fully rejected — nothing moved.
29
+ */
30
+ export type RequestKind = 'inflow' | 'outflow' | 'neutral';
31
+ /** One derived request row. Every field is a number, a code or an id. */
32
+ export interface RequestState {
33
+ /** `UserRequest.id`. */
34
+ id: string;
35
+ /**
36
+ * Id the loan contract is retrieved by — sourced from the `Initiated`
37
+ * event (format `${requestId}-${index}`). The agreements upstream keys
38
+ * contract metadata by EVENT id, not request id; passing `id` returns
39
+ * "Signature data not found". Empty string when there is no `Initiated`
40
+ * event (e.g. a withdrawal).
41
+ */
42
+ contractId: string;
43
+ /** Pool address, lowercased — the filter/join key. */
44
+ poolId: string;
45
+ /**
46
+ * Pool name exactly as it arrived. RAW: splitting it into a strategy name
47
+ * and its borrower-type subheading (kasu-ui's `splitPoolName`) is a
48
+ * display decision and stays in the application.
49
+ */
50
+ poolName: string;
51
+ /**
52
+ * Tranche name exactly as the subgraph reports it. RAW: apps call
53
+ * `getTrancheDisplayName(state.trancheName, { poolName: state.poolName })`
54
+ * at the view boundary. A renamed value must never reach matching or
55
+ * ranking code.
56
+ */
57
+ trancheName: string;
58
+ /** Tranche id — the resolve API re-renders a fixed-term contract against it. */
59
+ trancheId: string;
60
+ /** Fixed-term configId, `'0'` for a variable-rate request. */
61
+ fixedTermConfigId: string;
62
+ requestType: 'Deposit' | 'Withdrawal';
63
+ /** The subgraph status, untouched. Sticky — see `cycleClosed`. */
64
+ rawStatus: UserRequest['status'];
65
+ statusCode: RequestStatusCode;
66
+ kind: RequestKind;
67
+ /**
68
+ * The amount originally asked for, always positive. A cancelled request
69
+ * has its on-request `requestedAmount` zeroed by the subgraph, so the
70
+ * original is recovered from the `Initiated` event (see
71
+ * `initiatedAmount`).
72
+ */
73
+ requestedAmount: number;
74
+ /**
75
+ * The accepted figure as the subgraph reported it, or `null` when it
76
+ * reported none. `null` is NOT zero: an absent figure means "not known",
77
+ * and a caller that renders it as 0 states an outcome the chain has not
78
+ * given. The branch logic below reads `null` as 0 — exactly what kasu-ui's
79
+ * `num()` does — but the distinction survives into the row.
80
+ */
81
+ acceptedAmount: number | null;
82
+ /**
83
+ * `assetAmount` of the `Initiated` event, or `null` when the request
84
+ * carries no `Initiated` event. This is the cancelled-amount recovery:
85
+ * the subgraph resets a cancelled request's `requestedAmount` to 0 (the
86
+ * lender's effective balance is restored) and the original survives only
87
+ * here.
88
+ */
89
+ initiatedAmount: number | null;
90
+ /**
91
+ * The rejected figure the subgraph reported, parsed with the same `num`
92
+ * rule as the rest: an absent or unparseable value is 0. Unlike
93
+ * `acceptedAmount` this is NOT nullable — it feeds the partial-vs-complete
94
+ * branch, where "no figure" and "nothing rejected" mean the same thing.
95
+ */
96
+ rejectedAmount: number;
97
+ /**
98
+ * `assetAmount` of the reallocation event, or 0 when the request was not
99
+ * reallocated. The amount that LEFT the requested tranche — which is not
100
+ * necessarily `acceptedAmount`, because a partly-filled request can be
101
+ * reallocated for only part of itself.
102
+ */
103
+ reallocatedOutAmount: number;
104
+ /**
105
+ * RAW name of the tranche a reallocated deposit was accepted into, or
106
+ * `null` when there was no reallocation. RAW for the same reason
107
+ * `trancheName` is: the app calls `getTrancheDisplayName` on it at the
108
+ * view boundary, and a renamed value must never reach matching code.
109
+ */
110
+ reallocationTargetTrancheName: string | null;
111
+ /**
112
+ * The row's highest-resolution timestamp: the LATEST event, or
113
+ * `request.timestamp` when the timeline is empty or older. Unix seconds.
114
+ *
115
+ * `firstSubmissionTimestamp` says when the lender asked; this says when
116
+ * anything last happened to the request, which is what a "last updated"
117
+ * column and a recency sort need.
118
+ */
119
+ lastTimestamp: number;
120
+ /**
121
+ * The signed figure the row shows, chosen by the same branch logic
122
+ * kasu-ui uses: positive for an inflow, negative for an outflow, 0 for a
123
+ * cancelled or fully-rejected request.
124
+ */
125
+ amount: number;
126
+ /**
127
+ * Submissions bundled into this dNFT-aggregate row (`Initiated` +
128
+ * `Increased`). `> 1` is what drives kasu-ui's inline "(x2)".
129
+ */
130
+ submissionCount: number;
131
+ /**
132
+ * Timestamp of the FIRST submission in the bundle, or `null` when the
133
+ * bundle carries no submission event yet (the `Initiated` event has not
134
+ * indexed). kasu-ui substitutes `request.timestamp` there; that fallback
135
+ * is the application's to choose, so this layer reports the absence.
136
+ */
137
+ firstSubmissionTimestamp: number | null;
138
+ /** Has THIS request's cycle closed? — `!canCancel`. See `isCycleClosed`. */
139
+ cycleClosed: boolean;
140
+ /** The SDK's per-pool cancel signal, passed through. */
141
+ canCancel: boolean;
142
+ }
143
+ /**
144
+ * The submissions bundled into one dNFT-aggregate request row, input order
145
+ * preserved — one loan agreement per submission.
146
+ */
147
+ export declare function submissionEvents<T extends Pick<UserRequestEvent, 'requestType'>>(events: T[]): T[];
148
+ /** Count the submissions bundled into one dNFT-aggregate request row. */
149
+ export declare function countSubmissions(events: Pick<UserRequestEvent, 'requestType'>[]): number;
150
+ /**
151
+ * Timestamp of the FIRST submission in the bundle. Falls back to `fallback`
152
+ * when the `Initiated` event has not indexed yet — the caller decides what
153
+ * that is (kasu-ui passes the request's own timestamp).
154
+ */
155
+ export declare function firstSubmissionTimestamp(events: Pick<UserRequestEvent, 'requestType' | 'timestamp'>[], fallback: number): number;
156
+ /**
157
+ * The LATEST event timestamp, or `fallback` when the timeline is empty — or
158
+ * when every event predates it, because `fallback` seeds the reduction. That
159
+ * seeding is deliberate and is kasu-ui's behaviour: `request.timestamp` is a
160
+ * fact about the request, and an event indexed with an earlier clock must not
161
+ * make the row look older than the request itself.
162
+ */
163
+ export declare function lastEventTimestamp(events: Pick<UserRequestEvent, 'timestamp'>[], fallback: number): number;
164
+ /**
165
+ * Has THIS request's cycle closed? — the single open/closed signal behind the
166
+ * status vocabulary and behind Cancel.
167
+ *
168
+ * `request.canCancel` is the SDK's `isCancelable(status, poolId)` —
169
+ * `status !== 'Processed' && !isLendingPoolClearingPending(pool)`. It is
170
+ * per-POOL and reads the same condition the contract enforces on the cancel
171
+ * call — but it reads it ONCE, when the request was fetched. Nothing about
172
+ * this value is live, so a client that holds a request across a cycle close
173
+ * must refetch before acting on it.
174
+ *
175
+ * The raw subgraph `status` must NOT feed this: `'Processing'` is a STICKY
176
+ * historical marker set on the first partial fill and never reset, so gating
177
+ * on it would freeze a partly-filled request in Processing forever. A global
178
+ * settlement clock is equally wrong here — it is blind to whether THIS
179
+ * request's pool is already clearing.
180
+ */
181
+ export declare function isCycleClosed(request: Pick<UserRequest, 'canCancel'>): boolean;
182
+ /**
183
+ * Convert a `UserRequest` into a `RequestState`. Pure — no clock, no network,
184
+ * no copy.
185
+ *
186
+ * BRANCH ORDER (this IS the behaviour; it reproduces kasu-ui's
187
+ * `deriveTransactionView` check for check):
188
+ *
189
+ * 1. a `Cancelled` event → `cancelled`, neutral, 0
190
+ * 2. a withdrawal with a `Forced` event → `forced`, outflow, −accepted
191
+ * 3. a reallocated deposit → `reallocated`, inflow, +accepted
192
+ * 4. a withdrawal partly filled with a LIVE
193
+ * remainder (cycle still open) → `partial`, outflow, −accepted
194
+ * 5. resolved (`status === 'Processed'`):
195
+ * withdrawal, partly filled → `partial`, outflow, −accepted
196
+ * withdrawal, fully filled → `complete`, outflow, −accepted
197
+ * deposit, nothing accepted → `rejected`, neutral, 0
198
+ * deposit, part rejected → `partial`, inflow, +accepted
199
+ * deposit, fully accepted → `complete`, inflow, +accepted
200
+ * 6. otherwise → `pending`, ±requested
201
+ *
202
+ * `cancelled` is reachable ONLY from branch 1 — a Cancelled EVENT. No
203
+ * processing or resolved state can derive it.
204
+ *
205
+ * Branch 4 is checked BEFORE the resolved branch and gates on `isCycleClosed`
206
+ * (i.e. `canCancel`), never on the sticky raw status: a withdrawal that was
207
+ * partly filled returns to the queue with a live Cancel, and reading the raw
208
+ * status would strand it.
209
+ *
210
+ * WHAT THE APPLICATION STILL OWNS: the status word and the detail line beneath
211
+ * it; the tranche display rename (`getTrancheDisplayName` on `trancheName`
212
+ * and on `reallocationTargetTrancheName`, both of which are RAW here); the
213
+ * pool-name split; the amount format. The "view loan agreement" affordance is
214
+ * a fact, and it follows from two fields already here —
215
+ * `requestType === 'Deposit' && statusCode !== 'cancelled' && statusCode !== 'rejected'`
216
+ * — because neither a cancelled nor a fully-rejected deposit ever issued one,
217
+ * and withdrawals sign no agreement at all.
218
+ */
219
+ export declare function deriveRequestState(request: UserRequest): RequestState;
@@ -0,0 +1,218 @@
1
+ import { UserRequestStatus } from '../services/UserLending/subgraph-types';
2
+ /**
3
+ * Events that represent a lender SUBMISSION into the bundle. A dNFT position
4
+ * aggregates every submission the lender made into the same pool/tranche this
5
+ * cycle: the first is `Initiated`, each subsequent top-up is `Increased`.
6
+ * Everything else on the timeline (Accepted / Rejected / Cancelled /
7
+ * Reallocated / Forced) is an OUTCOME, not a request, and must not be counted.
8
+ */
9
+ const SUBMISSION_EVENTS = new Set(['Initiated', 'Increased']);
10
+ /**
11
+ * The submissions bundled into one dNFT-aggregate request row, input order
12
+ * preserved — one loan agreement per submission.
13
+ */
14
+ export function submissionEvents(events) {
15
+ return events.filter((e) => SUBMISSION_EVENTS.has(e.requestType));
16
+ }
17
+ /** Count the submissions bundled into one dNFT-aggregate request row. */
18
+ export function countSubmissions(events) {
19
+ return submissionEvents(events).length;
20
+ }
21
+ /**
22
+ * Timestamp of the FIRST submission in the bundle. Falls back to `fallback`
23
+ * when the `Initiated` event has not indexed yet — the caller decides what
24
+ * that is (kasu-ui passes the request's own timestamp).
25
+ */
26
+ export function firstSubmissionTimestamp(events, fallback) {
27
+ const submissions = submissionEvents(events);
28
+ if (submissions.length === 0)
29
+ return fallback;
30
+ return submissions.reduce((min, e) => (e.timestamp < min ? e.timestamp : min), Infinity);
31
+ }
32
+ /**
33
+ * The LATEST event timestamp, or `fallback` when the timeline is empty — or
34
+ * when every event predates it, because `fallback` seeds the reduction. That
35
+ * seeding is deliberate and is kasu-ui's behaviour: `request.timestamp` is a
36
+ * fact about the request, and an event indexed with an earlier clock must not
37
+ * make the row look older than the request itself.
38
+ */
39
+ export function lastEventTimestamp(events, fallback) {
40
+ return events.reduce((max, e) => (e.timestamp > max ? e.timestamp : max), fallback);
41
+ }
42
+ /**
43
+ * Has THIS request's cycle closed? — the single open/closed signal behind the
44
+ * status vocabulary and behind Cancel.
45
+ *
46
+ * `request.canCancel` is the SDK's `isCancelable(status, poolId)` —
47
+ * `status !== 'Processed' && !isLendingPoolClearingPending(pool)`. It is
48
+ * per-POOL and reads the same condition the contract enforces on the cancel
49
+ * call — but it reads it ONCE, when the request was fetched. Nothing about
50
+ * this value is live, so a client that holds a request across a cycle close
51
+ * must refetch before acting on it.
52
+ *
53
+ * The raw subgraph `status` must NOT feed this: `'Processing'` is a STICKY
54
+ * historical marker set on the first partial fill and never reset, so gating
55
+ * on it would freeze a partly-filled request in Processing forever. A global
56
+ * settlement clock is equally wrong here — it is blind to whether THIS
57
+ * request's pool is already clearing.
58
+ */
59
+ export function isCycleClosed(request) {
60
+ return !request.canCancel;
61
+ }
62
+ const isCancelled = (events) => events.some((e) => e.requestType === 'Cancelled');
63
+ const isForced = (events) => events.some((e) => e.requestType === 'Forced');
64
+ const initiatedEvent = (events) => events.find((e) => e.requestType === 'Initiated');
65
+ /**
66
+ * Subgraph behaviour: when a request is cancelled, the on-request
67
+ * `requestedAmount` field is reset to 0 (the lender's effective balance is
68
+ * restored). The original amount survives on the `Initiated` event's
69
+ * `assetAmount`. Recover from there so cancelled rows still carry the amount
70
+ * the lender originally asked for.
71
+ */
72
+ const initiatedAmountOf = (events) => {
73
+ const initiated = initiatedEvent(events);
74
+ return initiated ? Number(initiated.assetAmount || '0') : 0;
75
+ };
76
+ /**
77
+ * A deposit is REALLOCATED when the timeline carries a `Reallocated` event, or
78
+ * an `Accepted` event into a tranche other than the one requested.
79
+ */
80
+ const findReallocation = (events, originalTrancheId) => events.find((e) => e.requestType === 'Reallocated' ||
81
+ (e.requestType === 'Accepted' &&
82
+ e.trancheId.toLowerCase() !==
83
+ originalTrancheId.toLowerCase()));
84
+ /** kasu-ui's `num`: an absent or unparseable figure reads as 0. */
85
+ const num = (str) => {
86
+ const n = Number(str !== null && str !== void 0 ? str : '0');
87
+ return Number.isFinite(n) ? n : 0;
88
+ };
89
+ /** The same parse, keeping "the subgraph reported nothing" distinct from 0. */
90
+ const numOrNull = (str) => {
91
+ if (str === undefined || str === null || str.trim() === '')
92
+ return null;
93
+ const n = Number(str);
94
+ return Number.isFinite(n) ? n : null;
95
+ };
96
+ /**
97
+ * Convert a `UserRequest` into a `RequestState`. Pure — no clock, no network,
98
+ * no copy.
99
+ *
100
+ * BRANCH ORDER (this IS the behaviour; it reproduces kasu-ui's
101
+ * `deriveTransactionView` check for check):
102
+ *
103
+ * 1. a `Cancelled` event → `cancelled`, neutral, 0
104
+ * 2. a withdrawal with a `Forced` event → `forced`, outflow, −accepted
105
+ * 3. a reallocated deposit → `reallocated`, inflow, +accepted
106
+ * 4. a withdrawal partly filled with a LIVE
107
+ * remainder (cycle still open) → `partial`, outflow, −accepted
108
+ * 5. resolved (`status === 'Processed'`):
109
+ * withdrawal, partly filled → `partial`, outflow, −accepted
110
+ * withdrawal, fully filled → `complete`, outflow, −accepted
111
+ * deposit, nothing accepted → `rejected`, neutral, 0
112
+ * deposit, part rejected → `partial`, inflow, +accepted
113
+ * deposit, fully accepted → `complete`, inflow, +accepted
114
+ * 6. otherwise → `pending`, ±requested
115
+ *
116
+ * `cancelled` is reachable ONLY from branch 1 — a Cancelled EVENT. No
117
+ * processing or resolved state can derive it.
118
+ *
119
+ * Branch 4 is checked BEFORE the resolved branch and gates on `isCycleClosed`
120
+ * (i.e. `canCancel`), never on the sticky raw status: a withdrawal that was
121
+ * partly filled returns to the queue with a live Cancel, and reading the raw
122
+ * status would strand it.
123
+ *
124
+ * WHAT THE APPLICATION STILL OWNS: the status word and the detail line beneath
125
+ * it; the tranche display rename (`getTrancheDisplayName` on `trancheName`
126
+ * and on `reallocationTargetTrancheName`, both of which are RAW here); the
127
+ * pool-name split; the amount format. The "view loan agreement" affordance is
128
+ * a fact, and it follows from two fields already here —
129
+ * `requestType === 'Deposit' && statusCode !== 'cancelled' && statusCode !== 'rejected'`
130
+ * — because neither a cancelled nor a fully-rejected deposit ever issued one,
131
+ * and withdrawals sign no agreement at all.
132
+ */
133
+ export function deriveRequestState(request) {
134
+ var _a, _b, _c;
135
+ const isWithdrawal = request.requestType === 'Withdrawal';
136
+ const cancelled = isCancelled(request.events);
137
+ // Cancelled requests have `requestedAmount` zeroed on the request itself;
138
+ // pull the original value from the Initiated event so the row still
139
+ // carries "100 cancelled" instead of "0 cancelled".
140
+ const requested = cancelled
141
+ ? num(request.requestedAmount) || initiatedAmountOf(request.events)
142
+ : num(request.requestedAmount);
143
+ const accepted = num(request.acceptedAmount);
144
+ const rejected = num(request.rejectedAmount);
145
+ const forced = isWithdrawal && isForced(request.events);
146
+ const reallocation = !isWithdrawal && findReallocation(request.events, request.trancheId);
147
+ const initiated = initiatedEvent(request.events);
148
+ const base = {
149
+ id: request.id,
150
+ contractId: (_a = initiated === null || initiated === void 0 ? void 0 : initiated.id) !== null && _a !== void 0 ? _a : '',
151
+ poolId: request.lendingPool.id.toLowerCase(),
152
+ poolName: request.lendingPool.name,
153
+ trancheName: request.trancheName,
154
+ trancheId: request.trancheId,
155
+ fixedTermConfigId: (_c = (_b = request.fixedTermConfig) === null || _b === void 0 ? void 0 : _b.configId) !== null && _c !== void 0 ? _c : '0',
156
+ requestType: request.requestType,
157
+ rawStatus: request.status,
158
+ requestedAmount: requested,
159
+ acceptedAmount: numOrNull(request.acceptedAmount),
160
+ initiatedAmount: initiated
161
+ ? initiatedAmountOf(request.events)
162
+ : null,
163
+ rejectedAmount: rejected,
164
+ reallocatedOutAmount: reallocation ? num(reallocation.assetAmount) : 0,
165
+ reallocationTargetTrancheName: reallocation
166
+ ? reallocation.trancheName
167
+ : null,
168
+ lastTimestamp: lastEventTimestamp(request.events, request.timestamp),
169
+ submissionCount: countSubmissions(request.events),
170
+ // `firstSubmissionTimestamp` needs a fallback it will never use here:
171
+ // the bundle is non-empty on every path that reaches the call.
172
+ firstSubmissionTimestamp: countSubmissions(request.events) === 0
173
+ ? null
174
+ : firstSubmissionTimestamp(request.events, 0),
175
+ cycleClosed: isCycleClosed(request),
176
+ canCancel: request.canCancel,
177
+ };
178
+ // 1. Cancelled wins over everything — the ONLY path to `cancelled`.
179
+ if (cancelled) {
180
+ return Object.assign(Object.assign({}, base), { kind: 'neutral', amount: 0, statusCode: 'cancelled' });
181
+ }
182
+ // 2. Forced withdrawal (credit originator returned funds early).
183
+ if (forced) {
184
+ return Object.assign(Object.assign({}, base), { kind: 'outflow', amount: -accepted, statusCode: 'forced' });
185
+ }
186
+ // 3. Reallocated deposit (accepted into a different lending option).
187
+ if (reallocation) {
188
+ return Object.assign(Object.assign({}, base), { kind: 'inflow', amount: accepted, statusCode: 'reallocated' });
189
+ }
190
+ // 4. Withdrawal partly filled with a LIVE remainder: the request returns
191
+ // to the queue with a live Cancel. Checked BEFORE the resolved branch and
192
+ // via `isCycleClosed`, never via the sticky raw status.
193
+ if (isWithdrawal &&
194
+ accepted > 0 &&
195
+ accepted < requested &&
196
+ !isCycleClosed(request)) {
197
+ return Object.assign(Object.assign({}, base), { kind: 'outflow', amount: -accepted, statusCode: 'partial' });
198
+ }
199
+ // 5. Resolved — a rejection IS a resolution.
200
+ if (request.status === UserRequestStatus.PROCESSED) {
201
+ if (isWithdrawal) {
202
+ const partly = accepted < requested;
203
+ return Object.assign(Object.assign({}, base), { kind: 'outflow', amount: -accepted, statusCode: partly ? 'partial' : 'complete' });
204
+ }
205
+ // Deposit: full reject vs partial vs full accept.
206
+ if (accepted === 0) {
207
+ return Object.assign(Object.assign({}, base), { kind: 'neutral', amount: 0, statusCode: 'rejected' });
208
+ }
209
+ if (rejected > 0) {
210
+ return Object.assign(Object.assign({}, base), { kind: 'inflow', amount: accepted, statusCode: 'partial' });
211
+ }
212
+ return Object.assign(Object.assign({}, base), { kind: 'inflow', amount: accepted, statusCode: 'complete' });
213
+ }
214
+ // 6. Unresolved. `cycleClosed` tells the caller whether to render its
215
+ // "queued" or its "processing" word; the code is the same either way.
216
+ return Object.assign(Object.assign({}, base), { kind: isWithdrawal ? 'outflow' : 'inflow', amount: isWithdrawal ? -requested : requested, statusCode: 'pending' });
217
+ }
218
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/domain/requests.ts"],"names":[],"mappings":"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"}