@gearbox-protocol/sdk 15.1.0-next.21 → 15.1.0-next.23
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/new-sdk/prepare/PrepareApi.js +4 -4
- package/dist/cjs/sdk/accounts/intents/index.js +57 -28
- package/dist/cjs/sdk/accounts/intents/plan.js +40 -2
- package/dist/cjs/sdk/accounts/intents/realize.js +22 -12
- package/dist/cjs/sdk/accounts/intents/tail.js +120 -0
- package/dist/cjs/sdk/accounts/intents/utils/index.js +1 -0
- package/dist/cjs/sdk/accounts/intents/utils/router-path.js +32 -0
- package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +11 -0
- package/dist/cjs/sdk/positions/PositionsService.js +22 -11
- package/dist/esm/new-sdk/prepare/PrepareApi.js +4 -4
- package/dist/esm/sdk/accounts/intents/index.js +58 -29
- package/dist/esm/sdk/accounts/intents/plan.js +40 -3
- package/dist/esm/sdk/accounts/intents/realize.js +22 -12
- package/dist/esm/sdk/accounts/intents/tail.js +118 -0
- package/dist/esm/sdk/accounts/intents/utils/index.js +2 -2
- package/dist/esm/sdk/accounts/intents/utils/router-path.js +32 -1
- package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +11 -0
- package/dist/esm/sdk/positions/PositionsService.js +22 -11
- package/dist/types/new-sdk/prepare/types.d.ts +22 -8
- package/dist/types/sdk/accounts/intents/index.d.ts +13 -6
- package/dist/types/sdk/accounts/intents/plan.d.ts +18 -2
- package/dist/types/sdk/accounts/intents/realize.d.ts +7 -0
- package/dist/types/sdk/accounts/intents/tail.d.ts +52 -0
- package/dist/types/sdk/accounts/intents/types.d.ts +46 -10
- package/dist/types/sdk/accounts/intents/utils/index.d.ts +2 -2
- package/dist/types/sdk/accounts/intents/utils/router-path.d.ts +15 -1
- package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +4 -0
- package/dist/types/sdk/market/oracle/types.d.ts +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ClaimableWithdrawal } from "../withdrawal-compressor/types.js";
|
|
2
|
+
import { OnchainSDK } from "../../OnchainSDK.js";
|
|
3
|
+
import { CreditAccountSlice, DelayedStart, OperationState, ResumableIntent } from "./types.js";
|
|
4
|
+
import { AccountCalculatorOperation, StartDelayedWithdrawalOperation } from "./operations.js";
|
|
5
|
+
import "../../index.js";
|
|
6
|
+
import { AccountView, Step } from "./plan.js";
|
|
7
|
+
//#region src/sdk/accounts/intents/tail.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* The second half of a delayed intent: the claim, then whatever the intent
|
|
10
|
+
* still owes.
|
|
11
|
+
*
|
|
12
|
+
* Shared by the two callers that need it and must not disagree — the tail as
|
|
13
|
+
* it is previewed days later against the account that really exists, and the
|
|
14
|
+
* tail as it is projected the moment the request is made.
|
|
15
|
+
*/
|
|
16
|
+
declare function planTail(args: {
|
|
17
|
+
intent: ResumableIntent;
|
|
18
|
+
claimable: ClaimableWithdrawal;
|
|
19
|
+
view: AccountView;
|
|
20
|
+
}): Step[];
|
|
21
|
+
/**
|
|
22
|
+
* Where a delayed intent ends up, worked out at the moment it is started.
|
|
23
|
+
*
|
|
24
|
+
* A request is only half a withdrawal, so the state it lands in is not the
|
|
25
|
+
* answer to "what does this do to my position": the debt is still there, the
|
|
26
|
+
* payout has not been made, and the position sits in a phantom token. What the
|
|
27
|
+
* caller means is the far side — and that side can be walked now, because the
|
|
28
|
+
* request already fixes the claim it will be finished from.
|
|
29
|
+
*
|
|
30
|
+
* So the same tail {@link planTail} builds at claim time is built here against
|
|
31
|
+
* the account as the request leaves it, with the claim it is expected to bring,
|
|
32
|
+
* and walked by the same realiser — with one substitution: routed legs are
|
|
33
|
+
* priced by the oracle rather than the pathfinder, since the funds they trade
|
|
34
|
+
* do not exist yet and no calldata is being produced. The result is an
|
|
35
|
+
* estimate that the engine's guards are nevertheless applied to, so a request
|
|
36
|
+
* that would strand the account is refused before it is sent rather than
|
|
37
|
+
* discovered days later.
|
|
38
|
+
*/
|
|
39
|
+
declare function projectTail(args: {
|
|
40
|
+
/** The request as realised: the source spent, the phantom it produced. */
|
|
41
|
+
request: StartDelayedWithdrawalOperation;
|
|
42
|
+
delayed: DelayedStart;
|
|
43
|
+
/** The account the request was previewed against, for masks and market. */
|
|
44
|
+
creditAccount: CreditAccountSlice;
|
|
45
|
+
sdk: OnchainSDK;
|
|
46
|
+
quotaReserve: number | undefined;
|
|
47
|
+
}): Promise<{
|
|
48
|
+
state: OperationState;
|
|
49
|
+
operations: AccountCalculatorOperation[];
|
|
50
|
+
}>;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { planTail, projectTail };
|
|
@@ -81,7 +81,11 @@ interface OperationState {
|
|
|
81
81
|
type PreviewErrorReason = "debtOutOfRange" | "leverageOutOfRange" | "insufficientSourceBalance" |
|
|
82
82
|
/** Input token is not accepted by the flow (e.g. deposit of a non-underlying). */
|
|
83
83
|
"unsupportedCollateralToken" |
|
|
84
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* No route for the trade the plan needs: no pool pair between the tokens
|
|
86
|
+
* requested, several and none was picked, or the pathfinder itself found no
|
|
87
|
+
* path for the amounts involved.
|
|
88
|
+
*/
|
|
85
89
|
"unsupportedTokenPair" |
|
|
86
90
|
/**
|
|
87
91
|
* The intent cannot settle with a delay: the source has no redemption config,
|
|
@@ -93,9 +97,8 @@ type PreviewErrorReason = "debtOutOfRange" | "leverageOutOfRange" | "insufficien
|
|
|
93
97
|
/** A redemption of the same asset is already in flight. */
|
|
94
98
|
"withdrawalInProgress" |
|
|
95
99
|
/**
|
|
96
|
-
* The claim names no operation to resume: requested without an intent,
|
|
97
|
-
* through a compressor too old to report one
|
|
98
|
-
* engine no longer previews.
|
|
100
|
+
* The claim names no operation to resume: requested without an intent, or
|
|
101
|
+
* read through a compressor too old to report one.
|
|
99
102
|
*/
|
|
100
103
|
"noRecordedIntent" |
|
|
101
104
|
/** The facade or the pool behind it is paused: nothing can be done at all. */
|
|
@@ -146,10 +149,44 @@ interface DelayedStart {
|
|
|
146
149
|
* instead, which settles all of it in one transaction.
|
|
147
150
|
*/
|
|
148
151
|
settlement: "instant" | "delayed";
|
|
152
|
+
/**
|
|
153
|
+
* What the claim is expected to credit the account with once the redemption
|
|
154
|
+
* matures: the venue's payout token and the amount the request queued.
|
|
155
|
+
* `undefined` when the request settled on the spot and nothing is coming.
|
|
156
|
+
*
|
|
157
|
+
* An estimate, not a quote — the issuer prices the redemption when it pays
|
|
158
|
+
* out, and the state the intent is previewed against was read now.
|
|
159
|
+
*/
|
|
160
|
+
claim: {
|
|
161
|
+
token: Address;
|
|
162
|
+
amount: bigint;
|
|
163
|
+
} | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* The account as the request transaction alone leaves it: the source spent,
|
|
166
|
+
* the phantom of the in-flight redemption in its place, the debt untouched.
|
|
167
|
+
*
|
|
168
|
+
* This is the state the facade judges when the transaction lands, so it is
|
|
169
|
+
* the one the engine's guards are applied to — while the `preview` beside it
|
|
170
|
+
* is where the intent ends up, tail included, which is what a caller asking
|
|
171
|
+
* "what does this do to my position" means.
|
|
172
|
+
*/
|
|
173
|
+
afterRequest: OperationState;
|
|
149
174
|
}
|
|
150
175
|
/**
|
|
151
176
|
* What the leading half of a delayed intent yields: the request transaction,
|
|
152
177
|
* plus what it recorded for the tail.
|
|
178
|
+
*
|
|
179
|
+
* `operations` and `calls` are the request and nothing else — that is the only
|
|
180
|
+
* transaction there is to send now. `preview`, though, is where the intent
|
|
181
|
+
* ends: the state the account reaches once the redemption matures, is claimed
|
|
182
|
+
* and the tail runs, since that is what the caller asked for when they asked
|
|
183
|
+
* to withdraw. The half-way state the request itself lands in is
|
|
184
|
+
* {@link DelayedStart.afterRequest}, and both are validated before either is
|
|
185
|
+
* reported.
|
|
186
|
+
*
|
|
187
|
+
* The tail is projected from oracle prices rather than from a route — the funds
|
|
188
|
+
* it trades do not exist yet — so its half of the numbers is an estimate. What
|
|
189
|
+
* the transaction on offer does is not.
|
|
153
190
|
*/
|
|
154
191
|
type DelayedStartResult = {
|
|
155
192
|
ok: true;
|
|
@@ -406,14 +443,13 @@ type StartIntent = AddCollateralIntent | WithdrawAssetIntent | AdjustLeverageInt
|
|
|
406
443
|
*/
|
|
407
444
|
type DelayableIntent = AdjustLeverageIntent | WithdrawStrategyIntent;
|
|
408
445
|
/**
|
|
409
|
-
* A delayed intent this engine knows how to finish.
|
|
446
|
+
* A delayed intent this engine knows how to finish — every one of them.
|
|
410
447
|
*
|
|
411
|
-
* `CLOSE_ACCOUNT`
|
|
412
|
-
*
|
|
448
|
+
* `CLOSE_ACCOUNT` included: an exit is a plain multicall like any other
|
|
449
|
+
* operation here (sell everything, settle the loan, hand the rest over), not
|
|
450
|
+
* the facade's own close entry point, so the engine can build its tail too.
|
|
413
451
|
*/
|
|
414
|
-
type ResumableIntent =
|
|
415
|
-
type: "CLOSE_ACCOUNT";
|
|
416
|
-
}>;
|
|
452
|
+
type ResumableIntent = DelayedIntent;
|
|
417
453
|
/** Shared inputs plus the matured withdrawal the tail is built around. */
|
|
418
454
|
type FinishIntentProps = StartIntentProps & {
|
|
419
455
|
intent: ResumableIntent;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fetchCreditAccountSlice, toCreditAccountSlice } from "./credit-account-slice.js";
|
|
2
|
+
import { OpenStrategyLeg, RouterPaths, SwapLeg, createOraclePaths, createRouterPaths } from "./router-path.js";
|
|
2
3
|
import { adjustStateToSnapshot } from "./adjust-state-to-snapshot.js";
|
|
3
4
|
import { assembleOperationCalls } from "./assemble-operation-calls.js";
|
|
4
5
|
import { calcBorrowedAmountPlusInterestAndFees } from "./borrowed-amount-plus-interest-and-fees.js";
|
|
@@ -7,5 +8,4 @@ import { convertAmount } from "./convert-amount.js";
|
|
|
7
8
|
import { ConvertFn, LedgerSnapshot, OperationLedger } from "./ledger.js";
|
|
8
9
|
import { CandidateToken, isPhantomToken, isRedemptionPhantomToken, pickFattestNonPhantomToken, rankAccountTokens } from "./pick-token.js";
|
|
9
10
|
import { clearedQuotas, getQuotasForUpdate, quotasAfterUpdate } from "./quotas-for-update.js";
|
|
10
|
-
|
|
11
|
-
export { CandidateToken, ConvertFn, LedgerSnapshot, OpenStrategyLeg, OperationLedger, RouterPaths, SwapLeg, adjustStateToSnapshot, assembleOperationCalls, calcBorrowedAmountPlusInterestAndFees, clearedQuotas, convertAmount, createRouterPaths, eq, fetchCreditAccountSlice, getQuotasForUpdate, isPhantomToken, isRedemptionPhantomToken, pickFattestNonPhantomToken, quotasAfterUpdate, rankAccountTokens, toCreditAccountSlice, toRouterCaSlice, toTargetDecimals };
|
|
11
|
+
export { CandidateToken, ConvertFn, LedgerSnapshot, OpenStrategyLeg, OperationLedger, RouterPaths, SwapLeg, adjustStateToSnapshot, assembleOperationCalls, calcBorrowedAmountPlusInterestAndFees, clearedQuotas, convertAmount, createOraclePaths, createRouterPaths, eq, fetchCreditAccountSlice, getQuotasForUpdate, isPhantomToken, isRedemptionPhantomToken, pickFattestNonPhantomToken, quotasAfterUpdate, rankAccountTokens, toCreditAccountSlice, toRouterCaSlice, toTargetDecimals };
|
|
@@ -66,5 +66,19 @@ declare function createRouterPaths(args: {
|
|
|
66
66
|
creditAccount: CreditAccountSlice;
|
|
67
67
|
slippage: number;
|
|
68
68
|
}): RouterPaths;
|
|
69
|
+
/**
|
|
70
|
+
* The same door, priced by the oracle and opening onto no calldata.
|
|
71
|
+
*
|
|
72
|
+
* For a leg that cannot be quoted yet: the tail of a redemption trades funds
|
|
73
|
+
* that do not exist, along a route the pathfinder will only be able to build
|
|
74
|
+
* once they do. Asking it now would price a swap of nothing, so the amounts
|
|
75
|
+
* come from the oracle instead — an estimate with no slippage floor, which is
|
|
76
|
+
* all a projection days out can honestly be — and the walk yields a state
|
|
77
|
+
* rather than a transaction.
|
|
78
|
+
*/
|
|
79
|
+
declare function createOraclePaths(args: {
|
|
80
|
+
sdk: OnchainSDK;
|
|
81
|
+
creditAccount: CreditAccountSlice;
|
|
82
|
+
}): RouterPaths;
|
|
69
83
|
//#endregion
|
|
70
|
-
export { OpenStrategyLeg, RouterPaths, SwapLeg, createRouterPaths };
|
|
84
|
+
export { OpenStrategyLeg, RouterPaths, SwapLeg, createOraclePaths, createRouterPaths };
|
|
@@ -92,6 +92,10 @@ declare abstract class PriceOracleBaseContract<abi extends Abi | readonly unknow
|
|
|
92
92
|
* {@inheritDoc IPriceOracleContract.convertFromUSD}
|
|
93
93
|
**/
|
|
94
94
|
convertFromUSD(to: Address, amount: bigint, reserve?: boolean): bigint;
|
|
95
|
+
/**
|
|
96
|
+
* {@inheritDoc IPriceOracleContract.safeConvert}
|
|
97
|
+
**/
|
|
98
|
+
safeConvert(from: Address, to: Address, amount: bigint): bigint | null;
|
|
95
99
|
/**
|
|
96
100
|
* {@inheritDoc IPriceOracleContract.safeConvertToUSD}
|
|
97
101
|
**/
|
|
@@ -131,6 +131,15 @@ interface IPriceOracleContract extends IBaseContract {
|
|
|
131
131
|
* @param reserve - Use reserve feeds instead of main.
|
|
132
132
|
**/
|
|
133
133
|
convert: (from: Address, to: Address, amount: bigint, reserve?: boolean) => bigint;
|
|
134
|
+
/**
|
|
135
|
+
* Like {@link convert}, but returns `null` instead of throwing when either
|
|
136
|
+
* token cannot be priced (missing or unsuccessful feed).
|
|
137
|
+
*
|
|
138
|
+
* @param from - Source token address.
|
|
139
|
+
* @param to - Destination token address.
|
|
140
|
+
* @param amount - Amount in source-token decimals.
|
|
141
|
+
**/
|
|
142
|
+
safeConvert: (from: Address, to: Address, amount: bigint) => bigint | null;
|
|
134
143
|
/**
|
|
135
144
|
* Converts a token amount to its USD value using latest known prices.
|
|
136
145
|
*
|