@kasufinance/kasu-sdk 2.7.1 → 2.10.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 (88) hide show
  1. package/README.md +162 -7
  2. package/dist/bundle.cjs.js +2292 -449
  3. package/dist/bundle.esm.js +2253 -451
  4. package/dist/domain/batch-proof.d.ts +210 -0
  5. package/dist/domain/batch-proof.js +384 -0
  6. package/dist/domain/batch-proof.js.map +1 -0
  7. package/dist/domain/explorer-urls.d.ts +33 -0
  8. package/dist/domain/explorer-urls.js +38 -0
  9. package/dist/domain/explorer-urls.js.map +1 -0
  10. package/dist/domain/fixed-term.d.ts +74 -0
  11. package/dist/domain/fixed-term.js +86 -0
  12. package/dist/domain/fixed-term.js.map +1 -0
  13. package/dist/domain/index.d.ts +12 -2
  14. package/dist/domain/index.js +7 -2
  15. package/dist/domain/index.js.map +1 -1
  16. package/dist/domain/partners.d.ts +29 -0
  17. package/dist/domain/partners.js +20 -0
  18. package/dist/domain/partners.js.map +1 -1
  19. package/dist/domain/requests.d.ts +24 -0
  20. package/dist/domain/requests.js +33 -0
  21. package/dist/domain/requests.js.map +1 -1
  22. package/dist/domain/sponsored-calls.d.ts +74 -0
  23. package/dist/domain/sponsored-calls.js +156 -0
  24. package/dist/domain/sponsored-calls.js.map +1 -0
  25. package/dist/domain/yields.d.ts +121 -0
  26. package/dist/domain/yields.js +151 -0
  27. package/dist/domain/yields.js.map +1 -0
  28. package/dist/facade/calls.d.ts +59 -0
  29. package/dist/facade/calls.js +89 -0
  30. package/dist/facade/calls.js.map +1 -0
  31. package/dist/facade/chain-configs.js +5 -0
  32. package/dist/facade/chain-configs.js.map +1 -1
  33. package/dist/facade/flows.d.ts +40 -3
  34. package/dist/facade/flows.js +36 -3
  35. package/dist/facade/flows.js.map +1 -1
  36. package/dist/facade/index.d.ts +3 -1
  37. package/dist/facade/index.js +1 -0
  38. package/dist/facade/index.js.map +1 -1
  39. package/dist/facade/kasu.d.ts +8 -2
  40. package/dist/facade/kasu.js +17 -4
  41. package/dist/facade/kasu.js.map +1 -1
  42. package/dist/facade/strategies.d.ts +43 -2
  43. package/dist/facade/strategies.js +80 -4
  44. package/dist/facade/strategies.js.map +1 -1
  45. package/dist/facade/types.d.ts +18 -0
  46. package/dist/flows/batch-errors.d.ts +74 -0
  47. package/dist/flows/batch-errors.js +83 -0
  48. package/dist/flows/batch-errors.js.map +1 -0
  49. package/dist/flows/batch-submission.d.ts +223 -0
  50. package/dist/flows/batch-submission.js +321 -0
  51. package/dist/flows/batch-submission.js.map +1 -0
  52. package/dist/flows/deposit-flow.d.ts +128 -4
  53. package/dist/flows/deposit-flow.js +233 -4
  54. package/dist/flows/deposit-flow.js.map +1 -1
  55. package/dist/flows/index.d.ts +6 -2
  56. package/dist/flows/index.js +3 -1
  57. package/dist/flows/index.js.map +1 -1
  58. package/dist/flows/withdraw-flow.d.ts +95 -4
  59. package/dist/flows/withdraw-flow.js +107 -2
  60. package/dist/flows/withdraw-flow.js.map +1 -1
  61. package/dist/services/DataService/queries.js +1 -0
  62. package/dist/services/DataService/queries.js.map +1 -1
  63. package/dist/services/UserLending/user-lending.d.ts +13 -0
  64. package/dist/services/UserLending/user-lending.js +25 -4
  65. package/dist/services/UserLending/user-lending.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/domain/batch-proof.ts +576 -0
  68. package/src/domain/explorer-urls.ts +74 -0
  69. package/src/domain/fixed-term.ts +115 -0
  70. package/src/domain/index.ts +56 -0
  71. package/src/domain/partners.ts +35 -0
  72. package/src/domain/requests.ts +37 -0
  73. package/src/domain/sponsored-calls.ts +213 -0
  74. package/src/domain/yields.ts +189 -0
  75. package/src/facade/calls.ts +135 -0
  76. package/src/facade/chain-configs.ts +5 -0
  77. package/src/facade/flows.ts +35 -2
  78. package/src/facade/index.ts +3 -0
  79. package/src/facade/kasu.ts +32 -2
  80. package/src/facade/strategies.ts +98 -7
  81. package/src/facade/types.ts +19 -0
  82. package/src/flows/batch-errors.ts +118 -0
  83. package/src/flows/batch-submission.ts +511 -0
  84. package/src/flows/deposit-flow.ts +379 -7
  85. package/src/flows/index.ts +34 -1
  86. package/src/flows/withdraw-flow.ts +219 -10
  87. package/src/services/DataService/queries.ts +1 -0
  88. package/src/services/UserLending/user-lending.ts +38 -10
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The errors an atomic-batch submitter throws, in one module both
3
+ * `DepositFlow` and `submitBatch` import — so `instanceof` is one class
4
+ * whichever of them a consumer imports it through.
5
+ */
6
+ /**
7
+ * What a `depositBatch` port throws when it KNOWS the batch reverted — from a
8
+ * simulation before sending, from the submitter refusing to broadcast a batch
9
+ * that would revert, or from a mined receipt whose user operation reverted.
10
+ * The run ends `{ step: 'request', reason: 'reverted', revertError }`.
11
+ *
12
+ * `revertError` is the custom error the contract named (`'ClearingIsPending'`,
13
+ * `'UserNotKycd'`, …), exactly as the ABI declares it. Pass `''` when the
14
+ * batch is known to revert but not why: the consumer then renders its generic
15
+ * `reverted` copy, which is what an unknown name gets anyway.
16
+ *
17
+ * A revert is DEFINITIVE — nothing was deposited. Throw it only when that is
18
+ * known; anything less certain is a `BatchPendingError`.
19
+ */
20
+ export class BatchRevertedError extends Error {
21
+ constructor(revertError, message) {
22
+ super(message !== null && message !== void 0 ? message : `DepositFlow: the batch reverted${revertError ? ` with ${revertError}` : ''}`);
23
+ this.name = 'BatchRevertedError';
24
+ this.revertError = revertError;
25
+ // Keeps `instanceof` honest under a down-levelled build.
26
+ Object.setPrototypeOf(this, BatchRevertedError.prototype);
27
+ }
28
+ }
29
+ /**
30
+ * Every non-revert failure of a batch submission, carrying its outcome and a
31
+ * short code (`'status_timeout'`, `'receipt_unavailable'`, …).
32
+ *
33
+ * The message is fixed and names no party: the wallet-error classifier reads a
34
+ * thrown error's text for a USER rejection, and a relay outage worded "…wallet
35
+ * refused…" must never reach the lender as something they did.
36
+ *
37
+ * `outcome` has NO default. `failed` is the one outcome that invites a second
38
+ * deposit, so a port author has to spell it out — a `throw new
39
+ * BatchSubmissionError(code)` written in a catch block after the POST left
40
+ * must not quietly become "try again".
41
+ */
42
+ export class BatchSubmissionError extends Error {
43
+ constructor(code, outcome, options) {
44
+ super(`Batch submission ${outcome} (${code})`);
45
+ this.name = 'BatchSubmissionError';
46
+ this.code = code;
47
+ this.outcome = outcome;
48
+ // Set by hand: `Error`'s own `cause` option is ES2022.
49
+ if (options && 'cause' in options) {
50
+ Object.defineProperty(this, 'cause', {
51
+ value: options.cause,
52
+ enumerable: false,
53
+ writable: true,
54
+ configurable: true,
55
+ });
56
+ }
57
+ Object.setPrototypeOf(this, BatchSubmissionError.prototype);
58
+ }
59
+ }
60
+ /**
61
+ * The ambiguous outcome: the batch may have landed. An instance of
62
+ * `BatchSubmissionError` with `outcome: 'pending'`.
63
+ */
64
+ export class BatchPendingError extends BatchSubmissionError {
65
+ constructor(code, options) {
66
+ super(code, 'pending', options);
67
+ this.name = 'BatchPendingError';
68
+ Object.setPrototypeOf(this, BatchPendingError.prototype);
69
+ }
70
+ }
71
+ /** The outcome a thrown error stands for, or `null` if it is not a submission error. */
72
+ export function batchOutcomeOf(err) {
73
+ return err instanceof BatchSubmissionError ? err.outcome : null;
74
+ }
75
+ /**
76
+ * Nothing was deposited and nothing can be: a known revert, or a definitive
77
+ * `failed` refusal. Everything else — including an error this SDK did not
78
+ * produce — is NOT proof of that, and a consumer must not invite a retry on it.
79
+ */
80
+ export function isDefinitivelyNotSubmitted(err) {
81
+ return (err instanceof BatchRevertedError || batchOutcomeOf(err) === 'failed');
82
+ }
83
+ //# sourceMappingURL=batch-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-errors.js","sourceRoot":"","sources":["../../src/flows/batch-errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAGzC,YAAY,WAAmB,EAAE,OAAgB;QAC7C,KAAK,CACD,OAAO,aAAP,OAAO,cAAP,OAAO,GACH,kCACI,WAAW,CAAC,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC,CAAC,EAC3C,EAAE,CACT,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,yDAAyD;QACzD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC9D,CAAC;CACJ;AAiBD;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAI3C,YACI,IAAY,EACZ,OAA+B,EAC/B,OAA6B;QAE7B,KAAK,CAAC,oBAAoB,OAAO,KAAK,IAAI,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,uDAAuD;QACvD,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE;gBACjC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,UAAU,EAAE,KAAK;gBACjB,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,IAAI;aACrB,CAAC,CAAC;QACP,CAAC;QACD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,oBAAoB;IACvD,YAAY,IAAY,EAAE,OAA6B;QACnD,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACJ;AAED,wFAAwF;AACxF,MAAM,UAAU,cAAc,CAAC,GAAY;IACvC,OAAO,GAAG,YAAY,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAAY;IACnD,OAAO,CACH,GAAG,YAAY,kBAAkB,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,QAAQ,CACxE,CAAC;AACN,CAAC"}
@@ -0,0 +1,223 @@
1
+ import { DepositProof, DepositProofExpectation, ReceiptLike, UserOperationProof, UserOperationProofExpectation } from '../domain/batch-proof';
2
+ import { SponsoredCall } from '../domain/sponsored-calls';
3
+ import { WaitableTransaction } from './observable';
4
+ /**
5
+ * Submitting a sponsored atomic deposit batch, from the accepted calls to a
6
+ * PROVEN deposit — the polling policy and the outcome taxonomy, and nothing
7
+ * else. No relay vendor, no URL, no wallet: the app's ports do the I/O, and
8
+ * this decides what each answer MEANS.
9
+ *
10
+ * The one rule everything here serves: **an ambiguous result is never
11
+ * reported as failed.** "Failed" tells a lender to try again, and a batch that
12
+ * may already have moved the money must never invite a second deposit.
13
+ */
14
+ /** One call of the batch. Structurally `BatchCall`. */
15
+ export interface SubmitBatchCall {
16
+ to: string;
17
+ data: string;
18
+ }
19
+ /**
20
+ * One read of the submitted batch's status, already NORMALISED by the app's
21
+ * port — the vendor's status vocabulary stays in the app.
22
+ */
23
+ export type BatchStatusRead =
24
+ /** Mined: a transaction hash exists. */
25
+ {
26
+ kind: 'mined';
27
+ txHash: string;
28
+ userOperationHash?: string | null;
29
+ }
30
+ /** The vendor says, definitively, that it reverted: nothing deposited. */
31
+ | {
32
+ kind: 'reverted';
33
+ }
34
+ /**
35
+ * Final for the vendor but silent about the deposit, or the status read
36
+ * was refused: stop polling, outcome UNKNOWN (→ pending).
37
+ */
38
+ | {
39
+ kind: 'unknown';
40
+ code: string;
41
+ }
42
+ /** Not there yet, replaced, or a transient failure: ask again. */
43
+ | {
44
+ kind: 'again';
45
+ userOperationHash?: string | null;
46
+ };
47
+ export interface BatchSubmissionPorts<R extends ReceiptLike = ReceiptLike> {
48
+ /**
49
+ * Hand the batch to the submitter; resolve with its transaction id once it
50
+ * is ACCEPTED.
51
+ *
52
+ * Throw `BatchRevertedError` when it is known to revert, and
53
+ * `BatchSubmissionError(code, 'failed')` ONLY when nothing was sent — no
54
+ * session, a refusal before broadcast. Any other throw is read as
55
+ * PENDING: this cannot know whether an unrecognised error left before or
56
+ * after the batch was accepted. Resending the same signed request after an
57
+ * ambiguous answer is the port's business (it owns the wire protocol).
58
+ */
59
+ post(calls: readonly SubmitBatchCall[]): Promise<{
60
+ transactionId: string;
61
+ }>;
62
+ /** One status read. A throw is treated as `{ kind: 'again' }`. */
63
+ getStatus(transactionId: string): Promise<BatchStatusRead>;
64
+ /**
65
+ * The mined receipt. Bound it with a timeout of your own; a throw is
66
+ * PENDING (`receipt_unavailable`) — the batch was mined, its receipt was
67
+ * just not readable.
68
+ */
69
+ getReceipt(txHash: string): Promise<R>;
70
+ /** ms epoch. */
71
+ now(): number;
72
+ sleep(ms: number): Promise<void>;
73
+ }
74
+ export interface BatchPollingPolicy {
75
+ /** Delay before the second status read (the first is immediate). */
76
+ initialMs: number;
77
+ /** Ceiling on the delay between reads. */
78
+ maxMs: number;
79
+ /** Multiplier applied to the delay after each read, ≥ 1. */
80
+ backoff: number;
81
+ /** Stop polling — PENDING, never failed — after this long. */
82
+ timeoutMs: number;
83
+ }
84
+ /**
85
+ * First read at once, then 3 s backing off ×1.5 to a 10 s ceiling, for up to
86
+ * 10 minutes. Running out of time is PENDING: the batch was accepted and may
87
+ * still land.
88
+ */
89
+ export declare const DEFAULT_BATCH_POLLING_POLICY: Readonly<BatchPollingPolicy>;
90
+ /** A proven deposit: the `deposited` proof and the receipt it was read from. */
91
+ export interface ProvenBatch<R extends ReceiptLike = ReceiptLike> {
92
+ proof: Extract<DepositProof, {
93
+ kind: 'deposited';
94
+ }>;
95
+ receipt: R;
96
+ txHash: string;
97
+ }
98
+ /** What `submitBatch` resolves with once the batch is accepted. */
99
+ export interface BatchSubmission<R extends ReceiptLike = ReceiptLike> extends WaitableTransaction {
100
+ transactionId: string;
101
+ /**
102
+ * Polls to a mined receipt and proves the deposit in it. Resolves ONLY on
103
+ * a proven deposit. Rejects with `BatchRevertedError` when it definitively
104
+ * did not deposit, and with `BatchPendingError` for everything else.
105
+ */
106
+ wait(): Promise<ProvenBatch<R>>;
107
+ }
108
+ /**
109
+ * Submit `calls` and return once the submitter ACCEPTED them; `wait()` then
110
+ * polls and proves. Use it as the body of a `DepositFlow` `depositBatch`
111
+ * port, after `validateDepositBatchCalls` and the app's own signing:
112
+ *
113
+ * ```ts
114
+ * depositBatch: (calls) => {
115
+ * const { tranche, amount } = validateDepositBatchCalls(calls, expected);
116
+ * return submitBatch(
117
+ * // `pendingPool`: the strategy's pending pool, so only ITS
118
+ * // `DepositRequested` can prove the deposit.
119
+ * { calls, expect: { lender, tranche, amount, pendingPool } },
120
+ * { post, getStatus, getReceipt, now: Date.now, sleep },
121
+ * );
122
+ * },
123
+ * ```
124
+ *
125
+ * | what happened | outcome |
126
+ * | ---------------------------------------------------- | ---------------------------------------- |
127
+ * | `post` throws `BatchRevertedError` | rethrown — reverted, nothing deposited |
128
+ * | `post` throws `BatchSubmissionError` | rethrown with its own outcome |
129
+ * | `post` throws anything else | `BatchPendingError('post_unknown')` |
130
+ * | `post` resolves without a transaction id | `BatchPendingError('malformed_answer')` |
131
+ * | status `reverted` | `BatchRevertedError('')` |
132
+ * | status `unknown` | `BatchPendingError(code)` |
133
+ * | polling runs out of time | `BatchPendingError('status_timeout')` |
134
+ * | receipt unreadable | `BatchPendingError('receipt_unavailable')` |
135
+ * | receipt: user operation reverted | `BatchRevertedError(revertError)` |
136
+ * | receipt: this deposit not shown | `BatchPendingError('deposit_unproven:<reason>')` |
137
+ * | receipt: this lender's deposit, tranche and amount | resolves `ProvenBatch` |
138
+ *
139
+ * Nothing on this path ever produces a `failed` outcome: by the time a batch
140
+ * has been posted, only a revert proves that nothing was deposited.
141
+ */
142
+ export declare function submitBatch<R extends ReceiptLike = ReceiptLike>(input: {
143
+ calls: readonly SubmitBatchCall[];
144
+ /** What the receipt must show — see `proveDepositInReceipt`. */
145
+ expect: Omit<DepositProofExpectation, 'userOperationHash'>;
146
+ }, ports: BatchSubmissionPorts<R>, policy?: Partial<BatchPollingPolicy>): Promise<BatchSubmission<R>>;
147
+ /**
148
+ * What became of an earlier submission that ended PENDING — ONE status read,
149
+ * no polling — for an app's guard against lending twice:
150
+ *
151
+ * - `deposited` — mined, and the receipt proves the deposit;
152
+ * - `not-deposited` — definitively reverted (vendor status or the user
153
+ * operation's own flag);
154
+ * - `unknown` — anything else, including a read or receipt that failed.
155
+ *
156
+ * Only `not-deposited` may let a new lend proceed unprompted; `deposited`
157
+ * means the lender is told the earlier one landed (`already-submitted`).
158
+ */
159
+ export declare function checkBatchOutcome<R extends ReceiptLike = ReceiptLike>(transactionId: string, expect: Omit<DepositProofExpectation, 'userOperationHash'>, ports: Pick<BatchSubmissionPorts<R>, 'getStatus' | 'getReceipt'>): Promise<'deposited' | 'not-deposited' | 'unknown'>;
160
+ /**
161
+ * `BatchSubmissionPorts` for ONE sponsored call: the same status, receipt and
162
+ * clock ports — a relay client written for the deposit batch serves both —
163
+ * with a `post` that receives the call together with its relay `kind`, so the
164
+ * app never maps one from the other.
165
+ */
166
+ export interface SponsoredCallSubmissionPorts<R extends ReceiptLike = ReceiptLike> extends Omit<BatchSubmissionPorts<R>, 'post'> {
167
+ /**
168
+ * Hand the call to the submitter (`kind` and `[call]` in the relay's
169
+ * body); resolve with its transaction id once it is ACCEPTED. The same
170
+ * throw rules as `BatchSubmissionPorts.post`: `BatchRevertedError` when
171
+ * it is known to revert, `BatchSubmissionError(code, 'failed')` ONLY when
172
+ * nothing was sent, anything else is read as PENDING.
173
+ */
174
+ post(call: SponsoredCall): Promise<{
175
+ transactionId: string;
176
+ }>;
177
+ }
178
+ /** An executed call: the `executed` proof and the receipt it was read from. */
179
+ export interface ExecutedCall<R extends ReceiptLike = ReceiptLike> {
180
+ proof: Extract<UserOperationProof, {
181
+ kind: 'executed';
182
+ }>;
183
+ receipt: R;
184
+ txHash: string;
185
+ }
186
+ /** What `submitSponsoredCall` resolves with once the call is accepted. */
187
+ export interface SponsoredCallSubmission<R extends ReceiptLike = ReceiptLike> extends WaitableTransaction {
188
+ transactionId: string;
189
+ /**
190
+ * Polls to a mined receipt and proves the sender's operation EXECUTED.
191
+ * Rejects with `BatchRevertedError` when it definitively did not, and
192
+ * with `BatchPendingError` for everything else.
193
+ */
194
+ wait(): Promise<ExecutedCall<R>>;
195
+ }
196
+ /**
197
+ * `submitBatch` for ONE sponsored `LendingPoolManager` call — the body of a
198
+ * `WithdrawFlow` `submitCall` port, and of an app's cancel or
199
+ * withdraw-at-expiry action. Same post, same polling policy, same outcome
200
+ * table; the proof is `proveUserOperationInReceipt` (the sender's operation
201
+ * succeeded) instead of the deposit proof, and an unproven receipt is
202
+ * `call_unproven:<reason>`.
203
+ *
204
+ * ```ts
205
+ * submitCall: (call) =>
206
+ * submitSponsoredCall(
207
+ * { call, expect: { sender: lender } },
208
+ * { post: (c) => postToMyRelay(c.kind, [c.call]), getStatus, getReceipt, now, sleep },
209
+ * ),
210
+ * ```
211
+ *
212
+ * The call is checked against its kind before anything is posted — a known
213
+ * kind, exactly `{ to, data }`, and `data` opening with that kind's selector —
214
+ * and a mismatch is `BatchSubmissionError('call_mismatch', 'failed')`: nothing
215
+ * was sent. Build calls with `kasu.calls`, and this never fires.
216
+ *
217
+ * As on the deposit path, nothing after the post ever produces `failed`.
218
+ */
219
+ export declare function submitSponsoredCall<R extends ReceiptLike = ReceiptLike>(input: {
220
+ call: SponsoredCall;
221
+ /** Whose operation must have executed — see `proveUserOperationInReceipt`. */
222
+ expect: Omit<UserOperationProofExpectation, 'userOperationHash'>;
223
+ }, ports: SponsoredCallSubmissionPorts<R>, policy?: Partial<BatchPollingPolicy>): Promise<SponsoredCallSubmission<R>>;
@@ -0,0 +1,321 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { proveDepositInReceipt, proveUserOperationInReceipt, } from '../domain/batch-proof';
11
+ import { SPONSORED_CALL_KINDS, SPONSORED_CALL_SELECTORS, } from '../domain/sponsored-calls';
12
+ import { BatchPendingError, BatchRevertedError, BatchSubmissionError, } from './batch-errors';
13
+ /**
14
+ * First read at once, then 3 s backing off ×1.5 to a 10 s ceiling, for up to
15
+ * 10 minutes. Running out of time is PENDING: the batch was accepted and may
16
+ * still land.
17
+ */
18
+ export const DEFAULT_BATCH_POLLING_POLICY = Object.freeze({
19
+ initialMs: 3000,
20
+ maxMs: 10000,
21
+ backoff: 1.5,
22
+ timeoutMs: 10 * 60 * 1000,
23
+ });
24
+ function resolvePolicy(policy) {
25
+ var _a, _b, _c, _d;
26
+ const resolved = {
27
+ initialMs: (_a = policy === null || policy === void 0 ? void 0 : policy.initialMs) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_POLLING_POLICY.initialMs,
28
+ maxMs: (_b = policy === null || policy === void 0 ? void 0 : policy.maxMs) !== null && _b !== void 0 ? _b : DEFAULT_BATCH_POLLING_POLICY.maxMs,
29
+ backoff: (_c = policy === null || policy === void 0 ? void 0 : policy.backoff) !== null && _c !== void 0 ? _c : DEFAULT_BATCH_POLLING_POLICY.backoff,
30
+ timeoutMs: (_d = policy === null || policy === void 0 ? void 0 : policy.timeoutMs) !== null && _d !== void 0 ? _d : DEFAULT_BATCH_POLLING_POLICY.timeoutMs,
31
+ };
32
+ const { initialMs, maxMs, backoff, timeoutMs } = resolved;
33
+ if (!(Number.isFinite(initialMs) && initialMs > 0) ||
34
+ !(Number.isFinite(maxMs) && maxMs >= initialMs) ||
35
+ !(Number.isFinite(backoff) && backoff >= 1) ||
36
+ !(Number.isFinite(timeoutMs) && timeoutMs > 0)) {
37
+ throw new TypeError('submitBatch: invalid polling policy');
38
+ }
39
+ return resolved;
40
+ }
41
+ /**
42
+ * Submit `calls` and return once the submitter ACCEPTED them; `wait()` then
43
+ * polls and proves. Use it as the body of a `DepositFlow` `depositBatch`
44
+ * port, after `validateDepositBatchCalls` and the app's own signing:
45
+ *
46
+ * ```ts
47
+ * depositBatch: (calls) => {
48
+ * const { tranche, amount } = validateDepositBatchCalls(calls, expected);
49
+ * return submitBatch(
50
+ * // `pendingPool`: the strategy's pending pool, so only ITS
51
+ * // `DepositRequested` can prove the deposit.
52
+ * { calls, expect: { lender, tranche, amount, pendingPool } },
53
+ * { post, getStatus, getReceipt, now: Date.now, sleep },
54
+ * );
55
+ * },
56
+ * ```
57
+ *
58
+ * | what happened | outcome |
59
+ * | ---------------------------------------------------- | ---------------------------------------- |
60
+ * | `post` throws `BatchRevertedError` | rethrown — reverted, nothing deposited |
61
+ * | `post` throws `BatchSubmissionError` | rethrown with its own outcome |
62
+ * | `post` throws anything else | `BatchPendingError('post_unknown')` |
63
+ * | `post` resolves without a transaction id | `BatchPendingError('malformed_answer')` |
64
+ * | status `reverted` | `BatchRevertedError('')` |
65
+ * | status `unknown` | `BatchPendingError(code)` |
66
+ * | polling runs out of time | `BatchPendingError('status_timeout')` |
67
+ * | receipt unreadable | `BatchPendingError('receipt_unavailable')` |
68
+ * | receipt: user operation reverted | `BatchRevertedError(revertError)` |
69
+ * | receipt: this deposit not shown | `BatchPendingError('deposit_unproven:<reason>')` |
70
+ * | receipt: this lender's deposit, tranche and amount | resolves `ProvenBatch` |
71
+ *
72
+ * Nothing on this path ever produces a `failed` outcome: by the time a batch
73
+ * has been posted, only a revert proves that nothing was deposited.
74
+ */
75
+ export function submitBatch(input, ports, policy) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ const resolved = resolvePolicy(policy);
78
+ const transactionId = yield postOnce(() => ports.post(input.calls));
79
+ let settled = null;
80
+ return {
81
+ transactionId,
82
+ // Memoised: a second `wait()` reads the same outcome instead of
83
+ // polling the submitter twice.
84
+ wait: () => (settled !== null && settled !== void 0 ? settled : (settled = settle(transactionId, input.expect, ports, resolved))),
85
+ };
86
+ });
87
+ }
88
+ /**
89
+ * The post, and what its answer means: the transaction id, or the error the
90
+ * outcome table names. Shared by both submitters, so the two cannot come to
91
+ * disagree about which throws are ambiguous.
92
+ */
93
+ function postOnce(post) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ let accepted;
96
+ try {
97
+ accepted = yield post();
98
+ }
99
+ catch (err) {
100
+ if (err instanceof BatchRevertedError)
101
+ throw err;
102
+ if (err instanceof BatchSubmissionError)
103
+ throw err;
104
+ throw new BatchPendingError('post_unknown', { cause: err });
105
+ }
106
+ const transactionId = accepted === null || accepted === void 0 ? void 0 : accepted.transactionId;
107
+ if (typeof transactionId !== 'string' || transactionId === '') {
108
+ throw new BatchPendingError('malformed_answer');
109
+ }
110
+ return transactionId;
111
+ });
112
+ }
113
+ function readStatus(ports, transactionId) {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ try {
116
+ return yield ports.getStatus(transactionId);
117
+ }
118
+ catch (_a) {
119
+ return { kind: 'again' };
120
+ }
121
+ });
122
+ }
123
+ /** Poll until a mined hash, or a typed reason there will not be one. */
124
+ function waitForMined(transactionId, ports, policy) {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ var _a;
127
+ const deadline = ports.now() + policy.timeoutMs;
128
+ let userOperationHash = null;
129
+ let delay = policy.initialMs;
130
+ for (;;) {
131
+ const read = yield readStatus(ports, transactionId);
132
+ switch (read.kind) {
133
+ case 'mined':
134
+ if (typeof read.txHash !== 'string' || read.txHash === '') {
135
+ break; // a malformed "mined" is not an answer; ask again
136
+ }
137
+ return {
138
+ txHash: read.txHash,
139
+ userOperationHash: (_a = read.userOperationHash) !== null && _a !== void 0 ? _a : userOperationHash,
140
+ };
141
+ case 'reverted':
142
+ throw new BatchRevertedError('');
143
+ case 'unknown':
144
+ throw new BatchPendingError(read.code);
145
+ case 'again':
146
+ if (read.userOperationHash) {
147
+ userOperationHash = read.userOperationHash;
148
+ }
149
+ break;
150
+ default:
151
+ // A read the port did not normalise: not an answer.
152
+ break;
153
+ }
154
+ if (ports.now() + delay > deadline) {
155
+ throw new BatchPendingError('status_timeout');
156
+ }
157
+ yield ports.sleep(delay);
158
+ delay = Math.min(policy.maxMs, Math.round(delay * policy.backoff));
159
+ }
160
+ });
161
+ }
162
+ /** Poll to a mined hash and read its receipt; a receipt read that throws is PENDING. */
163
+ function minedReceipt(transactionId, ports, policy) {
164
+ return __awaiter(this, void 0, void 0, function* () {
165
+ const mined = yield waitForMined(transactionId, ports, policy);
166
+ try {
167
+ return {
168
+ receipt: yield ports.getReceipt(mined.txHash),
169
+ txHash: mined.txHash,
170
+ userOperationHash: mined.userOperationHash,
171
+ };
172
+ }
173
+ catch (err) {
174
+ throw new BatchPendingError('receipt_unavailable', { cause: err });
175
+ }
176
+ });
177
+ }
178
+ function settle(transactionId, expect, ports, policy) {
179
+ return __awaiter(this, void 0, void 0, function* () {
180
+ const mined = yield minedReceipt(transactionId, ports, policy);
181
+ let proof;
182
+ try {
183
+ proof = proveDepositInReceipt(mined.receipt, Object.assign(Object.assign({}, expect), { userOperationHash: mined.userOperationHash }));
184
+ }
185
+ catch (err) {
186
+ // A receipt the proof cannot even read proves nothing either way.
187
+ throw new BatchPendingError('deposit_unproven', { cause: err });
188
+ }
189
+ if (proof.kind === 'reverted')
190
+ throw new BatchRevertedError(proof.revertError);
191
+ if (proof.kind === 'unproven') {
192
+ // The proof's reason rides in the code: "no-user-operation" (the hash
193
+ // is not this lender's operation at all) and "no-deposit-requested"
194
+ // (the operation ran and shows no deposit) are the two things an
195
+ // operator reading the alert needs to tell apart first.
196
+ throw new BatchPendingError(`deposit_unproven:${proof.reason}`);
197
+ }
198
+ return { proof, receipt: mined.receipt, txHash: mined.txHash };
199
+ });
200
+ }
201
+ /**
202
+ * What became of an earlier submission that ended PENDING — ONE status read,
203
+ * no polling — for an app's guard against lending twice:
204
+ *
205
+ * - `deposited` — mined, and the receipt proves the deposit;
206
+ * - `not-deposited` — definitively reverted (vendor status or the user
207
+ * operation's own flag);
208
+ * - `unknown` — anything else, including a read or receipt that failed.
209
+ *
210
+ * Only `not-deposited` may let a new lend proceed unprompted; `deposited`
211
+ * means the lender is told the earlier one landed (`already-submitted`).
212
+ */
213
+ export function checkBatchOutcome(transactionId, expect, ports) {
214
+ return __awaiter(this, void 0, void 0, function* () {
215
+ var _a;
216
+ let read;
217
+ try {
218
+ read = yield ports.getStatus(transactionId);
219
+ }
220
+ catch (_b) {
221
+ return 'unknown';
222
+ }
223
+ if (read.kind === 'reverted')
224
+ return 'not-deposited';
225
+ if (read.kind !== 'mined' || typeof read.txHash !== 'string') {
226
+ return 'unknown';
227
+ }
228
+ try {
229
+ const receipt = yield ports.getReceipt(read.txHash);
230
+ const proof = proveDepositInReceipt(receipt, Object.assign(Object.assign({}, expect), { userOperationHash: (_a = read.userOperationHash) !== null && _a !== void 0 ? _a : null }));
231
+ if (proof.kind === 'deposited')
232
+ return 'deposited';
233
+ if (proof.kind === 'reverted')
234
+ return 'not-deposited';
235
+ return 'unknown';
236
+ }
237
+ catch (_c) {
238
+ return 'unknown';
239
+ }
240
+ });
241
+ }
242
+ /**
243
+ * `submitBatch` for ONE sponsored `LendingPoolManager` call — the body of a
244
+ * `WithdrawFlow` `submitCall` port, and of an app's cancel or
245
+ * withdraw-at-expiry action. Same post, same polling policy, same outcome
246
+ * table; the proof is `proveUserOperationInReceipt` (the sender's operation
247
+ * succeeded) instead of the deposit proof, and an unproven receipt is
248
+ * `call_unproven:<reason>`.
249
+ *
250
+ * ```ts
251
+ * submitCall: (call) =>
252
+ * submitSponsoredCall(
253
+ * { call, expect: { sender: lender } },
254
+ * { post: (c) => postToMyRelay(c.kind, [c.call]), getStatus, getReceipt, now, sleep },
255
+ * ),
256
+ * ```
257
+ *
258
+ * The call is checked against its kind before anything is posted — a known
259
+ * kind, exactly `{ to, data }`, and `data` opening with that kind's selector —
260
+ * and a mismatch is `BatchSubmissionError('call_mismatch', 'failed')`: nothing
261
+ * was sent. Build calls with `kasu.calls`, and this never fires.
262
+ *
263
+ * As on the deposit path, nothing after the post ever produces `failed`.
264
+ */
265
+ export function submitSponsoredCall(input, ports, policy) {
266
+ return __awaiter(this, void 0, void 0, function* () {
267
+ const resolved = resolvePolicy(policy);
268
+ if (!isWellFormedSponsoredCall(input.call)) {
269
+ throw new BatchSubmissionError('call_mismatch', 'failed');
270
+ }
271
+ const transactionId = yield postOnce(() => ports.post(input.call));
272
+ let settled = null;
273
+ return {
274
+ transactionId,
275
+ wait: () => (settled !== null && settled !== void 0 ? settled : (settled = settleCall(transactionId, input.expect, ports, resolved))),
276
+ };
277
+ });
278
+ }
279
+ function isWellFormedSponsoredCall(value) {
280
+ if (value === null || typeof value !== 'object')
281
+ return false;
282
+ const { kind, call } = value;
283
+ if (typeof kind !== 'string' ||
284
+ !SPONSORED_CALL_KINDS.includes(kind)) {
285
+ return false;
286
+ }
287
+ if (call === null || typeof call !== 'object')
288
+ return false;
289
+ const keys = Object.keys(call);
290
+ if (keys.length !== 2 || !keys.includes('to') || !keys.includes('data')) {
291
+ return false;
292
+ }
293
+ const { to, data } = call;
294
+ return (typeof to === 'string' &&
295
+ /^0x[0-9a-fA-F]{40}$/.test(to) &&
296
+ typeof data === 'string' &&
297
+ /^0x(?:[0-9a-fA-F]{2})*$/.test(data) &&
298
+ data
299
+ .toLowerCase()
300
+ .startsWith(SPONSORED_CALL_SELECTORS[kind]));
301
+ }
302
+ function settleCall(transactionId, expect, ports, policy) {
303
+ return __awaiter(this, void 0, void 0, function* () {
304
+ const mined = yield minedReceipt(transactionId, ports, policy);
305
+ let proof;
306
+ try {
307
+ proof = proveUserOperationInReceipt(mined.receipt, Object.assign(Object.assign({}, expect), { userOperationHash: mined.userOperationHash }));
308
+ }
309
+ catch (err) {
310
+ throw new BatchPendingError('call_unproven', { cause: err });
311
+ }
312
+ if (proof.kind === 'reverted') {
313
+ throw new BatchRevertedError(proof.revertError);
314
+ }
315
+ if (proof.kind === 'unproven') {
316
+ throw new BatchPendingError(`call_unproven:${proof.reason}`);
317
+ }
318
+ return { proof, receipt: mined.receipt, txHash: mined.txHash };
319
+ });
320
+ }
321
+ //# sourceMappingURL=batch-submission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-submission.js","sourceRoot":"","sources":["../../src/flows/batch-submission.ts"],"names":[],"mappings":"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"}