@gearbox-protocol/sdk 16.0.0-next.42 → 16.0.0-next.43
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/dist/cjs/model/index.js +4 -0
- package/dist/cjs/model/result.js +27 -0
- package/dist/cjs/onchain/accounts/intents/tail.js +1 -1
- package/dist/cjs/onchain/accounts/withdrawal-compressor/errors.js +14 -14
- package/dist/cjs/onchain/index.js +0 -1
- package/dist/cjs/onchain/market/zapper/errors.js +13 -12
- package/dist/cjs/onchain/validation/index.js +0 -1
- package/dist/cjs/preview/index.js +4 -1
- package/dist/cjs/preview/parse/errors.js +25 -22
- package/dist/cjs/preview/preview/errors.js +12 -11
- package/dist/cjs/preview/preview/previewOperation.js +41 -10
- package/dist/cjs/preview/simulate/errors.js +18 -17
- package/dist/cjs/sdk/execute/ExecuteApi.js +1 -1
- package/dist/cjs/sdk/index.js +1 -1
- package/dist/cjs/sdk/prepare/PrepareApi.js +198 -278
- package/dist/cjs/sdk/prepare/errors.js +5 -2
- package/dist/cjs/sdk/prepare/index.js +1 -1
- package/dist/esm/model/index.js +2 -1
- package/dist/esm/model/result.js +24 -0
- package/dist/esm/onchain/accounts/intents/tail.js +1 -1
- package/dist/esm/onchain/accounts/withdrawal-compressor/errors.js +14 -14
- package/dist/esm/onchain/index.js +2 -2
- package/dist/esm/onchain/market/zapper/errors.js +13 -12
- package/dist/esm/onchain/validation/index.js +2 -2
- package/dist/esm/preview/index.js +4 -2
- package/dist/esm/preview/parse/errors.js +25 -22
- package/dist/esm/preview/preview/errors.js +12 -11
- package/dist/esm/preview/preview/previewOperation.js +41 -10
- package/dist/esm/preview/simulate/errors.js +18 -17
- package/dist/esm/sdk/execute/ExecuteApi.js +1 -1
- package/dist/esm/sdk/index.js +2 -2
- package/dist/esm/sdk/prepare/PrepareApi.js +199 -279
- package/dist/esm/sdk/prepare/errors.js +5 -2
- package/dist/esm/sdk/prepare/index.js +2 -2
- package/dist/types/model/errors.d.ts +3 -31
- package/dist/types/model/index.d.ts +3 -2
- package/dist/types/model/result.d.ts +48 -0
- package/dist/types/onchain/accounts/withdrawal-compressor/errors.d.ts +18 -5
- package/dist/types/onchain/index.d.ts +2 -2
- package/dist/types/onchain/market/zapper/errors.d.ts +20 -6
- package/dist/types/onchain/validation/index.d.ts +2 -2
- package/dist/types/preview/index.d.ts +5 -3
- package/dist/types/preview/parse/errors.d.ts +36 -11
- package/dist/types/preview/preview/errors.d.ts +17 -5
- package/dist/types/preview/preview/index.d.ts +2 -2
- package/dist/types/preview/preview/previewOperation.d.ts +21 -2
- package/dist/types/preview/simulate/errors.d.ts +21 -8
- package/dist/types/sdk/execute/types.d.ts +6 -11
- package/dist/types/sdk/index.d.ts +3 -3
- package/dist/types/sdk/prepare/PrepareApi.d.ts +29 -26
- package/dist/types/sdk/prepare/errors.d.ts +56 -19
- package/dist/types/sdk/prepare/index.d.ts +3 -3
- package/dist/types/sdk/prepare/types.d.ts +73 -74
- package/dist/types/sdk/preview/PreviewNamespace.d.ts +4 -1
- package/dist/types/sdk/preview/types.d.ts +7 -3
- package/package.json +11 -2
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { hexEq } from "../../onchain/utils/hex.js";
|
|
2
2
|
import { MultichainConstruct } from "../../onchain/base/MultichainConstruct.js";
|
|
3
|
+
import { sdkErr, sdkOk } from "../../model/result.js";
|
|
4
|
+
import "../../model/index.js";
|
|
3
5
|
import { toToken } from "../../onchain/validation/token.js";
|
|
4
6
|
import { toCreditAccountSlice } from "../../onchain/accounts/intents/utils/credit-account-slice.js";
|
|
5
7
|
import { CreditAccountOperationsService } from "../../onchain/accounts/intents/index.js";
|
|
6
8
|
import "../../onchain/index.js";
|
|
7
|
-
import { creditAccountNotFound, noStrategyTargetCollateral,
|
|
9
|
+
import { creditAccountNotFound, noStrategyTargetCollateral, toRefusalError, unexpectedFailure } from "./errors.js";
|
|
8
10
|
import { withdrawableCollaterals } from "./withdrawable-collaterals.js";
|
|
9
11
|
//#region src/sdk/prepare/PrepareApi.ts
|
|
10
12
|
/**
|
|
@@ -15,15 +17,18 @@ import { withdrawableCollaterals } from "./withdrawable-collaterals.js";
|
|
|
15
17
|
* protocol knowledge stays in `CreditAccountOperationsService` and
|
|
16
18
|
* `PoolService`.
|
|
17
19
|
*
|
|
18
|
-
* A prepared operation names one chain
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* A prepared operation names one chain and reads it directly: there is no
|
|
21
|
+
* second source to fall back to, so a chain the SDK does not cover, or one
|
|
22
|
+
* that fails the read, is a failure of the whole request rather than a thinner
|
|
23
|
+
* answer.
|
|
22
24
|
*
|
|
23
|
-
* No method here throws. Every way a preparation can
|
|
24
|
-
* refusals, the
|
|
25
|
-
* engine raises — comes back
|
|
26
|
-
*
|
|
25
|
+
* No refusable async method here throws. Every way such a preparation can
|
|
26
|
+
* fail — the market's own refusals, the ones the namespace decides itself, and
|
|
27
|
+
* anything the chain or the engine raises — comes back in the failure half of
|
|
28
|
+
* its `SDKReturn`, under the codes that method's signature names. A caller
|
|
29
|
+
* writes one branch, not a branch and a `try`. The synchronous LP methods and
|
|
30
|
+
* the bare `max*` reads throw on bugs and lifecycle errors instead, see
|
|
31
|
+
* {@link IOpportunitiesPrepare}.
|
|
27
32
|
**/
|
|
28
33
|
var PrepareApi = class extends MultichainConstruct {
|
|
29
34
|
#ensureFresh;
|
|
@@ -31,54 +36,28 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
31
36
|
super(sdk);
|
|
32
37
|
this.#ensureFresh = ensureFresh;
|
|
33
38
|
}
|
|
34
|
-
async queryChain(props) {
|
|
35
|
-
await this.#ensureFresh?.([this.sdk.chain(props.network).chainId]);
|
|
36
|
-
return super.queryChain(props);
|
|
37
|
-
}
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* escape.
|
|
42
|
-
*
|
|
43
|
-
* So every method below answers instead of rejecting, and a caller has one
|
|
44
|
-
* thing to branch on. "This cannot be done" and "we could not find out" are
|
|
45
|
-
* still told apart, by `error.code`: only the second is
|
|
46
|
-
* `unexpectedFailure`, and only it marks the chain failed in `meta`.
|
|
40
|
+
* The chain an async method reads, revalidated first so the state it is
|
|
41
|
+
* about to weigh is no older than the SDK's freshness bar.
|
|
47
42
|
**/
|
|
48
|
-
async #
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
network: chainId,
|
|
52
|
-
run
|
|
53
|
-
});
|
|
54
|
-
} catch (e) {
|
|
55
|
-
return {
|
|
56
|
-
data: {
|
|
57
|
-
success: false,
|
|
58
|
-
error: unexpectedFailure(e)
|
|
59
|
-
},
|
|
60
|
-
meta: { chains: [failedChain(chainId, e)] }
|
|
61
|
-
};
|
|
62
|
-
}
|
|
43
|
+
async #chain(chainId) {
|
|
44
|
+
await this.#ensureFresh?.([this.sdk.chain(chainId).chainId]);
|
|
45
|
+
return this.sdk.chain(chainId);
|
|
63
46
|
}
|
|
64
47
|
/**
|
|
65
48
|
* {@inheritDoc IOpportunitiesPrepare.finalize}
|
|
66
49
|
**/
|
|
67
50
|
async finalize(position, params) {
|
|
68
|
-
|
|
51
|
+
try {
|
|
52
|
+
const sdk = await this.#chain(position.chainId);
|
|
53
|
+
const at = stateBlock(sdk);
|
|
69
54
|
const intent = resumable(params.intent ?? params.claimable.intent);
|
|
70
|
-
if (!intent) return {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
detail: void 0
|
|
75
|
-
})
|
|
76
|
-
};
|
|
55
|
+
if (!intent) return sdkErr(toRefusalError({
|
|
56
|
+
reason: "noRecordedIntent",
|
|
57
|
+
detail: void 0
|
|
58
|
+
}));
|
|
77
59
|
const creditAccount = await slice(sdk, position.creditAccount);
|
|
78
|
-
if (!creditAccount) return
|
|
79
|
-
success: false,
|
|
80
|
-
error: creditAccountNotFound(position.creditAccount)
|
|
81
|
-
};
|
|
60
|
+
if (!creditAccount) return sdkErr(creditAccountNotFound(position.creditAccount));
|
|
82
61
|
return planned(await service(sdk).finishIntent({
|
|
83
62
|
intent,
|
|
84
63
|
claimable: toClaimableWithdrawal(params.claimable),
|
|
@@ -86,27 +65,15 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
86
65
|
sdk,
|
|
87
66
|
slippage: params.slippage,
|
|
88
67
|
quotaReserve: params.quotaReserve
|
|
89
|
-
}));
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* {@inheritDoc IOpportunitiesPrepare.deposit}
|
|
94
|
-
**/
|
|
95
|
-
deposit(pool, params) {
|
|
96
|
-
try {
|
|
97
|
-
return this.#depositPlan(pool, params);
|
|
68
|
+
}), at);
|
|
98
69
|
} catch (e) {
|
|
99
|
-
return
|
|
100
|
-
success: false,
|
|
101
|
-
error: unexpectedFailure(e)
|
|
102
|
-
};
|
|
70
|
+
return sdkErr(unexpectedFailure(e));
|
|
103
71
|
}
|
|
104
72
|
}
|
|
105
73
|
/**
|
|
106
|
-
*
|
|
107
|
-
* nothing for the pool or the chain it was handed.
|
|
74
|
+
* {@inheritDoc IOpportunitiesPrepare.deposit}
|
|
108
75
|
**/
|
|
109
|
-
|
|
76
|
+
deposit(pool, params) {
|
|
110
77
|
const chain = this.sdk.chain(pool.chainId);
|
|
111
78
|
const { marketRegister, pools } = chain;
|
|
112
79
|
const tokenIn = params.tokenIn ?? marketRegister.findByPool(pool.pool).pool.underlying;
|
|
@@ -128,32 +95,17 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
128
95
|
meta: pools.getDepositMetadata(pool.pool, tokenIn, tokenOut)
|
|
129
96
|
});
|
|
130
97
|
if (!call) return unroutable(chain, tokenIn, tokenOut);
|
|
131
|
-
return {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
};
|
|
98
|
+
return sdkOk({
|
|
99
|
+
operations: [],
|
|
100
|
+
state,
|
|
101
|
+
calls: call.calls,
|
|
102
|
+
...stateBlock(chain)
|
|
103
|
+
});
|
|
139
104
|
}
|
|
140
105
|
/**
|
|
141
106
|
* {@inheritDoc IOpportunitiesPrepare.withdraw}
|
|
142
107
|
**/
|
|
143
108
|
withdraw(pool, params) {
|
|
144
|
-
try {
|
|
145
|
-
return this.#withdrawPlan(pool, params);
|
|
146
|
-
} catch (e) {
|
|
147
|
-
return {
|
|
148
|
-
success: false,
|
|
149
|
-
error: unexpectedFailure(e)
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* {@inheritDoc PrepareApi.depositPlan}
|
|
155
|
-
**/
|
|
156
|
-
#withdrawPlan(pool, params) {
|
|
157
109
|
const chain = this.sdk.chain(pool.chainId);
|
|
158
110
|
const { pools } = chain;
|
|
159
111
|
const tokenIn = params.tokenIn ?? pool.pool;
|
|
@@ -173,32 +125,17 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
173
125
|
meta: pools.getWithdrawalMetadata(pool.pool, tokenIn, tokenOut),
|
|
174
126
|
mode: "withdraw"
|
|
175
127
|
});
|
|
176
|
-
return {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
};
|
|
128
|
+
return sdkOk({
|
|
129
|
+
operations: [],
|
|
130
|
+
state,
|
|
131
|
+
calls,
|
|
132
|
+
...stateBlock(chain)
|
|
133
|
+
});
|
|
184
134
|
}
|
|
185
135
|
/**
|
|
186
136
|
* {@inheritDoc IOpportunitiesPrepare.redeem}
|
|
187
137
|
**/
|
|
188
138
|
redeem(pool, params) {
|
|
189
|
-
try {
|
|
190
|
-
return this.#redeemPlan(pool, params);
|
|
191
|
-
} catch (e) {
|
|
192
|
-
return {
|
|
193
|
-
success: false,
|
|
194
|
-
error: unexpectedFailure(e)
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* {@inheritDoc PrepareApi.depositPlan}
|
|
200
|
-
**/
|
|
201
|
-
#redeemPlan(pool, params) {
|
|
202
139
|
const chain = this.sdk.chain(pool.chainId);
|
|
203
140
|
const { pools } = chain;
|
|
204
141
|
const tokenIn = params.tokenIn ?? pool.pool;
|
|
@@ -218,25 +155,22 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
218
155
|
meta: pools.getWithdrawalMetadata(pool.pool, tokenIn, tokenOut),
|
|
219
156
|
mode: "redeem"
|
|
220
157
|
});
|
|
221
|
-
return {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
};
|
|
158
|
+
return sdkOk({
|
|
159
|
+
operations: [],
|
|
160
|
+
state,
|
|
161
|
+
calls,
|
|
162
|
+
...stateBlock(chain)
|
|
163
|
+
});
|
|
229
164
|
}
|
|
230
165
|
/**
|
|
231
166
|
* {@inheritDoc IOpportunitiesPrepare.openNewStrategy}
|
|
232
167
|
**/
|
|
233
168
|
async openNewStrategy(strategy, params) {
|
|
234
|
-
|
|
169
|
+
try {
|
|
170
|
+
const sdk = await this.#chain(strategy.chainId);
|
|
171
|
+
const at = stateBlock(sdk);
|
|
235
172
|
const targetToken = params.targetToken ?? sdk.marketRegister.findCreditManager(strategy.creditManager).strategyTargetCollateral;
|
|
236
|
-
if (!targetToken) return
|
|
237
|
-
success: false,
|
|
238
|
-
error: noStrategyTargetCollateral(strategy.creditManager)
|
|
239
|
-
};
|
|
173
|
+
if (!targetToken) return sdkErr(noStrategyTargetCollateral(strategy.creditManager));
|
|
240
174
|
return opened(await service(sdk).openStrategyIntent({
|
|
241
175
|
sdk,
|
|
242
176
|
creditManager: strategy.creditManager,
|
|
@@ -246,8 +180,10 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
246
180
|
leftoverBalances: params.leftoverBalances,
|
|
247
181
|
slippage: params.slippage,
|
|
248
182
|
quotaReserve: params.quotaReserve
|
|
249
|
-
}));
|
|
250
|
-
})
|
|
183
|
+
}), at);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
return sdkErr(unexpectedFailure(e));
|
|
186
|
+
}
|
|
251
187
|
}
|
|
252
188
|
/**
|
|
253
189
|
* {@inheritDoc IOpportunitiesPrepare.depositStrategy}
|
|
@@ -278,19 +214,11 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
278
214
|
* {@inheritDoc IOpportunitiesPrepare.maxWithdraw}
|
|
279
215
|
**/
|
|
280
216
|
async maxWithdraw(position) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
};
|
|
287
|
-
return {
|
|
288
|
-
success: true,
|
|
289
|
-
data: await service(sdk).maxWithdraw({
|
|
290
|
-
creditAccount,
|
|
291
|
-
sdk
|
|
292
|
-
})
|
|
293
|
-
};
|
|
217
|
+
const sdk = await this.#chain(position.chainId);
|
|
218
|
+
const creditAccount = await this.#account(sdk, position);
|
|
219
|
+
return service(sdk).maxWithdraw({
|
|
220
|
+
creditAccount,
|
|
221
|
+
sdk
|
|
294
222
|
});
|
|
295
223
|
}
|
|
296
224
|
/**
|
|
@@ -308,19 +236,11 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
308
236
|
* {@inheritDoc IOpportunitiesPrepare.maxRepay}
|
|
309
237
|
**/
|
|
310
238
|
async maxRepay(position) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
};
|
|
317
|
-
return {
|
|
318
|
-
success: true,
|
|
319
|
-
data: await service(sdk).maxRepay({
|
|
320
|
-
creditAccount,
|
|
321
|
-
sdk
|
|
322
|
-
})
|
|
323
|
-
};
|
|
239
|
+
const sdk = await this.#chain(position.chainId);
|
|
240
|
+
const creditAccount = await this.#account(sdk, position);
|
|
241
|
+
return service(sdk).maxRepay({
|
|
242
|
+
creditAccount,
|
|
243
|
+
sdk
|
|
324
244
|
});
|
|
325
245
|
}
|
|
326
246
|
/**
|
|
@@ -377,75 +297,92 @@ var PrepareApi = class extends MultichainConstruct {
|
|
|
377
297
|
* {@inheritDoc IOpportunitiesPrepare.maxWithdrawCollateral}
|
|
378
298
|
**/
|
|
379
299
|
async maxWithdrawCollateral(position, token, targetHF) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
success: true,
|
|
388
|
-
data: await service(sdk).maxWithdrawCollateral({
|
|
389
|
-
creditAccount,
|
|
390
|
-
sdk,
|
|
391
|
-
token,
|
|
392
|
-
targetHF
|
|
393
|
-
})
|
|
394
|
-
};
|
|
300
|
+
const sdk = await this.#chain(position.chainId);
|
|
301
|
+
const creditAccount = await this.#account(sdk, position);
|
|
302
|
+
return service(sdk).maxWithdrawCollateral({
|
|
303
|
+
creditAccount,
|
|
304
|
+
sdk,
|
|
305
|
+
token,
|
|
306
|
+
targetHF
|
|
395
307
|
});
|
|
396
308
|
}
|
|
397
309
|
/**
|
|
398
|
-
*
|
|
399
|
-
*
|
|
310
|
+
* The account a bare `max*` read weighs. These reads answer a number, not
|
|
311
|
+
* an envelope, so an account the markets do not hold is thrown rather than
|
|
312
|
+
* described, see {@link IOpportunitiesPrepare.maxWithdraw}.
|
|
313
|
+
**/
|
|
314
|
+
async #account(sdk, position) {
|
|
315
|
+
const creditAccount = await slice(sdk, position.creditAccount);
|
|
316
|
+
if (!creditAccount) throw new Error(creditAccountNotFound(position.creditAccount).message);
|
|
317
|
+
return creditAccount;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Shared path of the two flows that sell a position asset, and therefore
|
|
321
|
+
* have two routes to offer: one account read, one intent, both routes
|
|
322
|
+
* quoted. Every refusal, the crash wrap included, carries `refused` so a
|
|
323
|
+
* form can say which routes were ruled out and why.
|
|
324
|
+
*
|
|
325
|
+
* @typeParam X - The codes the calling flow can raise beyond the shared
|
|
326
|
+
* ones, per the engine trace its signature spells out.
|
|
400
327
|
**/
|
|
401
328
|
async #startRoutes(position, options, intent) {
|
|
402
329
|
try {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}));
|
|
415
|
-
}
|
|
416
|
-
});
|
|
330
|
+
const sdk = await this.#chain(position.chainId);
|
|
331
|
+
const at = stateBlock(sdk);
|
|
332
|
+
const creditAccount = await slice(sdk, position.creditAccount);
|
|
333
|
+
if (!creditAccount) return neitherRoute(creditAccountNotFound(position.creditAccount));
|
|
334
|
+
return routed(await service(sdk).intentRoutes({
|
|
335
|
+
intent,
|
|
336
|
+
creditAccount,
|
|
337
|
+
sdk,
|
|
338
|
+
slippage: options.slippage,
|
|
339
|
+
quotaReserve: options.quotaReserve
|
|
340
|
+
}), at);
|
|
417
341
|
} catch (e) {
|
|
418
|
-
return
|
|
419
|
-
data: neitherRoute(unexpectedFailure(e)),
|
|
420
|
-
meta: { chains: [failedChain(position.chainId, e)] }
|
|
421
|
-
};
|
|
342
|
+
return neitherRoute(unexpectedFailure(e));
|
|
422
343
|
}
|
|
423
344
|
}
|
|
424
345
|
/**
|
|
425
346
|
* Shared path of the five flows that act on an existing account: read the
|
|
426
|
-
* account, then run the intent through the engine.
|
|
347
|
+
* account, then run the intent through the engine. Whatever the chain or
|
|
348
|
+
* the engine throws on the way is described as `unexpectedFailure` instead
|
|
349
|
+
* of escaping, so the flow always answers.
|
|
350
|
+
*
|
|
351
|
+
* @typeParam X - The codes the calling flow can raise beyond the shared
|
|
352
|
+
* ones, per the engine trace its signature spells out.
|
|
427
353
|
**/
|
|
428
354
|
async #startIntent(position, options, intent) {
|
|
429
|
-
|
|
355
|
+
try {
|
|
356
|
+
const sdk = await this.#chain(position.chainId);
|
|
357
|
+
const at = stateBlock(sdk);
|
|
430
358
|
const creditAccount = await slice(sdk, position.creditAccount);
|
|
431
|
-
if (!creditAccount) return
|
|
432
|
-
success: false,
|
|
433
|
-
error: creditAccountNotFound(position.creditAccount)
|
|
434
|
-
};
|
|
359
|
+
if (!creditAccount) return sdkErr(creditAccountNotFound(position.creditAccount));
|
|
435
360
|
return planned(await service(sdk).startIntent({
|
|
436
361
|
intent,
|
|
437
362
|
creditAccount,
|
|
438
363
|
sdk,
|
|
439
364
|
slippage: options.slippage,
|
|
440
365
|
quotaReserve: options.quotaReserve
|
|
441
|
-
}));
|
|
442
|
-
})
|
|
366
|
+
}), at);
|
|
367
|
+
} catch (e) {
|
|
368
|
+
return sdkErr(unexpectedFailure(e));
|
|
369
|
+
}
|
|
443
370
|
}
|
|
444
371
|
};
|
|
445
372
|
function service(sdk) {
|
|
446
373
|
return new CreditAccountOperationsService(sdk);
|
|
447
374
|
}
|
|
448
375
|
/**
|
|
376
|
+
* Reads the block the SDK's loaded state stands at — the same state every
|
|
377
|
+
* preparation below is computed from, so it is the block the result reports.
|
|
378
|
+
**/
|
|
379
|
+
function stateBlock(sdk) {
|
|
380
|
+
return {
|
|
381
|
+
blockNumber: Number(sdk.currentBlock),
|
|
382
|
+
timestamp: Number(sdk.timestamp)
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
449
386
|
* The account the request names, or nothing where the markets this SDK is
|
|
450
387
|
* connected to hold no such account — closed since it was listed, or named on
|
|
451
388
|
* the wrong chain. Read rather than thrown, so the caller gets a code for it.
|
|
@@ -485,89 +422,59 @@ function toClaimableWithdrawal(claimable) {
|
|
|
485
422
|
};
|
|
486
423
|
}
|
|
487
424
|
/**
|
|
425
|
+
* The engine's refusal as one flow's failure half.
|
|
426
|
+
*
|
|
427
|
+
* The engine answers with the open union of every reason it can raise
|
|
428
|
+
* anywhere; which of them a given flow actually reaches is the engine trace
|
|
429
|
+
* written into the public signatures. This cast is the one place the open
|
|
430
|
+
* union is narrowed onto them — a code added to or removed from a flow has to
|
|
431
|
+
* move its signature, which `types.test-d.ts` pins.
|
|
432
|
+
**/
|
|
433
|
+
function refusal(issue) {
|
|
434
|
+
return sdkErr(toRefusalError(issue));
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
488
437
|
* A flow with two routes, refused before either could be quoted: the error is
|
|
489
438
|
* the same one any other flow would report, with nothing to say about the
|
|
490
439
|
* routes because neither was reached.
|
|
491
440
|
**/
|
|
492
441
|
function neitherRoute(error) {
|
|
493
|
-
return {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
instant: void 0,
|
|
499
|
-
delayed: void 0
|
|
500
|
-
}
|
|
442
|
+
return sdkErr({
|
|
443
|
+
...error,
|
|
444
|
+
refused: {
|
|
445
|
+
instant: void 0,
|
|
446
|
+
delayed: void 0
|
|
501
447
|
}
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* The chain entry for a request that was answered with
|
|
506
|
-
* {@link UnexpectedFailureError}: the read did not happen, so the metadata says
|
|
507
|
-
* so rather than reporting a block it never got.
|
|
508
|
-
**/
|
|
509
|
-
function failedChain(chainId, error) {
|
|
510
|
-
return {
|
|
511
|
-
chainId,
|
|
512
|
-
status: "error",
|
|
513
|
-
source: "onchain",
|
|
514
|
-
error
|
|
515
|
-
};
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* A pool route the market does not offer, as the refusal a caller reads.
|
|
519
|
-
*
|
|
520
|
-
* `to` is absent where {@link lpRoute} found no output to name at all, which
|
|
521
|
-
* is the usual way of it; both are present where a pair exists but nothing of
|
|
522
|
-
* ours implements it.
|
|
523
|
-
**/
|
|
524
|
-
function unroutable(sdk, from, to) {
|
|
525
|
-
return {
|
|
526
|
-
success: false,
|
|
527
|
-
error: toPrepareError({
|
|
528
|
-
reason: "unsupportedTokenPair",
|
|
529
|
-
detail: {
|
|
530
|
-
from: toToken(sdk, from),
|
|
531
|
-
to: to === void 0 ? void 0 : toToken(sdk, to)
|
|
532
|
-
}
|
|
533
|
-
})
|
|
534
|
-
};
|
|
448
|
+
});
|
|
535
449
|
}
|
|
536
450
|
/**
|
|
537
451
|
* The engine's answer, as the envelope the namespace speaks in: what the
|
|
538
|
-
* operation comes to under `data`,
|
|
539
|
-
* numbers, see
|
|
452
|
+
* operation comes to under `data`, stamped with the block it was computed
|
|
453
|
+
* from, or the refusal as an error carrying its own numbers, see
|
|
454
|
+
* {@link refusal}.
|
|
540
455
|
*
|
|
541
456
|
* The engine keeps its `ok` union — it is the shape the planners, the guards
|
|
542
457
|
* and their tests are written against — and the boundary is the one place the
|
|
543
458
|
* two vocabularies meet.
|
|
544
459
|
**/
|
|
545
|
-
function planned(result) {
|
|
546
|
-
if (!result.ok) return
|
|
547
|
-
success: false,
|
|
548
|
-
error: toPrepareError(result)
|
|
549
|
-
};
|
|
460
|
+
function planned(result, at) {
|
|
461
|
+
if (!result.ok) return refusal(result);
|
|
550
462
|
const { operations, state, calls } = result;
|
|
551
|
-
return {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
};
|
|
463
|
+
return sdkOk({
|
|
464
|
+
operations,
|
|
465
|
+
state,
|
|
466
|
+
calls,
|
|
467
|
+
...at
|
|
468
|
+
});
|
|
559
469
|
}
|
|
560
470
|
/**
|
|
561
471
|
* {@inheritDoc planned}
|
|
562
472
|
**/
|
|
563
|
-
function opened(result) {
|
|
564
|
-
return result.ok ? {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
} :
|
|
568
|
-
success: false,
|
|
569
|
-
error: toPrepareError(result)
|
|
570
|
-
};
|
|
473
|
+
function opened(result, at) {
|
|
474
|
+
return result.ok ? sdkOk({
|
|
475
|
+
state: result.state,
|
|
476
|
+
...at
|
|
477
|
+
}) : refusal(result);
|
|
571
478
|
}
|
|
572
479
|
/**
|
|
573
480
|
* {@inheritDoc planned}
|
|
@@ -576,40 +483,53 @@ function opened(result) {
|
|
|
576
483
|
* missing, and it stays on the error when neither route answered, since that is
|
|
577
484
|
* the same question asked of a request that has no viable half at all.
|
|
578
485
|
**/
|
|
579
|
-
function routed(result) {
|
|
486
|
+
function routed(result, at) {
|
|
580
487
|
if (!result.ok) {
|
|
581
488
|
const { refused, ...issue } = result;
|
|
582
|
-
return {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
refused
|
|
587
|
-
}
|
|
588
|
-
};
|
|
489
|
+
return sdkErr({
|
|
490
|
+
...toRefusalError(issue),
|
|
491
|
+
refused
|
|
492
|
+
});
|
|
589
493
|
}
|
|
590
494
|
const { instant, delayed, refused } = result;
|
|
591
|
-
return {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
495
|
+
return sdkOk({
|
|
496
|
+
instant: instant && {
|
|
497
|
+
operations: instant.operations,
|
|
498
|
+
state: instant.state,
|
|
499
|
+
calls: instant.calls,
|
|
500
|
+
...at
|
|
501
|
+
},
|
|
502
|
+
delayed: delayed && {
|
|
503
|
+
operations: delayed.operations,
|
|
504
|
+
state: delayed.state,
|
|
505
|
+
calls: delayed.calls,
|
|
506
|
+
delayed: delayed.delayed,
|
|
507
|
+
...at
|
|
508
|
+
},
|
|
509
|
+
refused,
|
|
510
|
+
...at
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* A pool route the market does not offer, as the refusal a caller reads.
|
|
515
|
+
*
|
|
516
|
+
* `to` is absent where {@link lpRoute} found no output to name at all, which
|
|
517
|
+
* is the usual way of it; both are present where a pair exists but nothing of
|
|
518
|
+
* ours implements it.
|
|
519
|
+
**/
|
|
520
|
+
function unroutable(sdk, from, to) {
|
|
521
|
+
return sdkErr(toRefusalError({
|
|
522
|
+
reason: "unsupportedTokenPair",
|
|
523
|
+
detail: {
|
|
524
|
+
from: toToken(sdk, from),
|
|
525
|
+
to: to === void 0 ? void 0 : toToken(sdk, to)
|
|
606
526
|
}
|
|
607
|
-
};
|
|
527
|
+
}));
|
|
608
528
|
}
|
|
609
529
|
/**
|
|
610
530
|
* Picks the route the operation takes out of `tokenIn`, as a value rather than
|
|
611
531
|
* an exception: an unroutable or ambiguous pair is a request the caller can
|
|
612
|
-
* fix, so it belongs in the
|
|
532
|
+
* fix, so it belongs in the failure half alongside the strategy refusals.
|
|
613
533
|
*
|
|
614
534
|
* A pool with no route out of the input reports it by throwing, hence the
|
|
615
535
|
* catch; a requested output is checked against the list rather than trusted,
|
|
@@ -34,8 +34,11 @@ const MESSAGES = {
|
|
|
34
34
|
* {@link MESSAGES}. A malformed transaction is spelled out rather than spread,
|
|
35
35
|
* because its detail names a `code` and a `message` of its own and they are not
|
|
36
36
|
* the envelope's.
|
|
37
|
+
*
|
|
38
|
+
* Generic over the issue it is handed, so a call site that already knows the
|
|
39
|
+
* reason gets that reason's error back rather than a union to narrow again.
|
|
37
40
|
**/
|
|
38
|
-
function
|
|
41
|
+
function toRefusalError(issue) {
|
|
39
42
|
if (issue.reason === "malformedTransaction") return {
|
|
40
43
|
code: "malformedTransaction",
|
|
41
44
|
message: MESSAGES.malformedTransaction,
|
|
@@ -83,4 +86,4 @@ function unexpectedFailure(thrown) {
|
|
|
83
86
|
};
|
|
84
87
|
}
|
|
85
88
|
//#endregion
|
|
86
|
-
export { creditAccountNotFound, noStrategyTargetCollateral,
|
|
89
|
+
export { creditAccountNotFound, noStrategyTargetCollateral, toRefusalError, unexpectedFailure };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IntentPreviewError, raise, refuse } from "../../onchain/validation/refusal.js";
|
|
2
|
-
import { creditAccountNotFound, noStrategyTargetCollateral,
|
|
2
|
+
import { creditAccountNotFound, noStrategyTargetCollateral, toRefusalError, unexpectedFailure } from "./errors.js";
|
|
3
3
|
import { PrepareApi } from "./PrepareApi.js";
|
|
4
4
|
import "./types.js";
|
|
5
|
-
export { IntentPreviewError, PrepareApi, creditAccountNotFound, noStrategyTargetCollateral, raise, refuse,
|
|
5
|
+
export { IntentPreviewError, PrepareApi, creditAccountNotFound, noStrategyTargetCollateral, raise, refuse, toRefusalError, unexpectedFailure };
|