@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.
- package/README.md +162 -7
- package/dist/bundle.cjs.js +2292 -449
- package/dist/bundle.esm.js +2253 -451
- package/dist/domain/batch-proof.d.ts +210 -0
- package/dist/domain/batch-proof.js +384 -0
- package/dist/domain/batch-proof.js.map +1 -0
- package/dist/domain/explorer-urls.d.ts +33 -0
- package/dist/domain/explorer-urls.js +38 -0
- package/dist/domain/explorer-urls.js.map +1 -0
- package/dist/domain/fixed-term.d.ts +74 -0
- package/dist/domain/fixed-term.js +86 -0
- package/dist/domain/fixed-term.js.map +1 -0
- package/dist/domain/index.d.ts +12 -2
- package/dist/domain/index.js +7 -2
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/partners.d.ts +29 -0
- package/dist/domain/partners.js +20 -0
- package/dist/domain/partners.js.map +1 -1
- package/dist/domain/requests.d.ts +24 -0
- package/dist/domain/requests.js +33 -0
- package/dist/domain/requests.js.map +1 -1
- package/dist/domain/sponsored-calls.d.ts +74 -0
- package/dist/domain/sponsored-calls.js +156 -0
- package/dist/domain/sponsored-calls.js.map +1 -0
- package/dist/domain/yields.d.ts +121 -0
- package/dist/domain/yields.js +151 -0
- package/dist/domain/yields.js.map +1 -0
- package/dist/facade/calls.d.ts +59 -0
- package/dist/facade/calls.js +89 -0
- package/dist/facade/calls.js.map +1 -0
- package/dist/facade/chain-configs.js +5 -0
- package/dist/facade/chain-configs.js.map +1 -1
- package/dist/facade/flows.d.ts +40 -3
- package/dist/facade/flows.js +36 -3
- package/dist/facade/flows.js.map +1 -1
- package/dist/facade/index.d.ts +3 -1
- package/dist/facade/index.js +1 -0
- package/dist/facade/index.js.map +1 -1
- package/dist/facade/kasu.d.ts +8 -2
- package/dist/facade/kasu.js +17 -4
- package/dist/facade/kasu.js.map +1 -1
- package/dist/facade/strategies.d.ts +43 -2
- package/dist/facade/strategies.js +80 -4
- package/dist/facade/strategies.js.map +1 -1
- package/dist/facade/types.d.ts +18 -0
- package/dist/flows/batch-errors.d.ts +74 -0
- package/dist/flows/batch-errors.js +83 -0
- package/dist/flows/batch-errors.js.map +1 -0
- package/dist/flows/batch-submission.d.ts +223 -0
- package/dist/flows/batch-submission.js +321 -0
- package/dist/flows/batch-submission.js.map +1 -0
- package/dist/flows/deposit-flow.d.ts +128 -4
- package/dist/flows/deposit-flow.js +233 -4
- package/dist/flows/deposit-flow.js.map +1 -1
- package/dist/flows/index.d.ts +6 -2
- package/dist/flows/index.js +3 -1
- package/dist/flows/index.js.map +1 -1
- package/dist/flows/withdraw-flow.d.ts +95 -4
- package/dist/flows/withdraw-flow.js +107 -2
- package/dist/flows/withdraw-flow.js.map +1 -1
- package/dist/services/DataService/queries.js +1 -0
- package/dist/services/DataService/queries.js.map +1 -1
- package/dist/services/UserLending/user-lending.d.ts +13 -0
- package/dist/services/UserLending/user-lending.js +25 -4
- package/dist/services/UserLending/user-lending.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/batch-proof.ts +576 -0
- package/src/domain/explorer-urls.ts +74 -0
- package/src/domain/fixed-term.ts +115 -0
- package/src/domain/index.ts +56 -0
- package/src/domain/partners.ts +35 -0
- package/src/domain/requests.ts +37 -0
- package/src/domain/sponsored-calls.ts +213 -0
- package/src/domain/yields.ts +189 -0
- package/src/facade/calls.ts +135 -0
- package/src/facade/chain-configs.ts +5 -0
- package/src/facade/flows.ts +35 -2
- package/src/facade/index.ts +3 -0
- package/src/facade/kasu.ts +32 -2
- package/src/facade/strategies.ts +98 -7
- package/src/facade/types.ts +19 -0
- package/src/flows/batch-errors.ts +118 -0
- package/src/flows/batch-submission.ts +511 -0
- package/src/flows/deposit-flow.ts +379 -7
- package/src/flows/index.ts +34 -1
- package/src/flows/withdraw-flow.ts +219 -10
- package/src/services/DataService/queries.ts +1 -0
- 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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"}
|