@gearbox-protocol/sdk 14.12.0-next.30 → 14.12.0-next.31

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.
@@ -22,70 +22,106 @@ __export(buildDelayedPreview_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(buildDelayedPreview_exports);
24
24
  var import_viem = require("viem");
25
+ var import_common_utils = require("../../common-utils/index.js");
25
26
  var import_sdk = require("../../sdk/index.js");
26
27
  var import_types = require("./types.js");
27
- function buildDelayedPreview(state, before, detected, convert) {
28
+ function buildDelayedPreview(afterInstant, before, detected, convert) {
28
29
  const { request, intent } = detected;
29
- const post = state.clone();
30
+ const post = afterInstant.clone();
31
+ const converter = makeSafeConverter(convert);
32
+ const claimed = applyClaim(post, request);
33
+ const collateralWithdrawn = new import_sdk.AssetsMap();
34
+ switch (intent?.type) {
35
+ case "CLOSE_ACCOUNT":
36
+ return buildClosePreview(post, converter);
37
+ case "DECREASE_LEVERAGE":
38
+ repayFromClaim(post, request.claimToken, converter.convert, claimed);
39
+ break;
40
+ case "WITHDRAW_COLLATERAL": {
41
+ const withdrawn = import_common_utils.BigIntMath.min(
42
+ intent.withdrawAmount,
43
+ post.balances.getOrZero(intent.withdrawToken)
44
+ );
45
+ if (withdrawn > 0n) {
46
+ post.balances.dec(intent.withdrawToken, withdrawn);
47
+ collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
48
+ }
49
+ const claimSpentOnWithdrawal = (0, import_viem.isAddressEqual)(
50
+ intent.withdrawToken,
51
+ request.claimToken
52
+ ) ? withdrawn : 0n;
53
+ repayFromClaim(
54
+ post,
55
+ request.claimToken,
56
+ converter.convert,
57
+ import_common_utils.BigIntMath.max(claimed - claimSpentOnWithdrawal, 0n)
58
+ );
59
+ break;
60
+ }
61
+ default:
62
+ break;
63
+ }
64
+ return buildAdjustPreview(post, before, collateralWithdrawn, converter);
65
+ }
66
+ function makeSafeConverter(convert) {
30
67
  let error;
31
- const safeConvert = (token, to, amount) => {
32
- try {
33
- return convert(token, to, amount);
34
- } catch {
35
- error ??= {
36
- code: import_types.ERROR_UNPRICEABLE_TOKEN,
37
- message: `cannot price token ${token}`
38
- };
39
- return 0n;
68
+ return {
69
+ convert: (token, to, amount) => {
70
+ try {
71
+ return convert(token, to, amount);
72
+ } catch {
73
+ error ??= {
74
+ code: import_types.ERROR_UNPRICEABLE_TOKEN,
75
+ message: `cannot price token ${token}`
76
+ };
77
+ return 0n;
78
+ }
79
+ },
80
+ get error() {
81
+ return error;
40
82
  }
41
83
  };
84
+ }
85
+ function applyClaim(post, request) {
42
86
  const claimed = post.balances.getOrZero(request.phantomToken);
43
87
  post.balances.upsert(request.phantomToken, 0n);
44
88
  post.quotas.upsert(request.phantomToken, 0n);
45
89
  post.balances.inc(request.claimToken, claimed);
46
- if (intent?.type === "CLOSE_ACCOUNT") {
47
- const totalValue2 = post.balances.sum(
48
- (token, balance) => balance > 0n ? safeConvert(token, post.underlying, balance) : 0n
49
- );
50
- const receivedAmount = totalValue2 > post.totalDebt ? totalValue2 - post.totalDebt : 0n;
51
- const preview2 = {
52
- operation: "CloseCreditAccount",
53
- permanent: true,
54
- creditManager: post.creditManager,
55
- creditAccount: post.creditAccount,
56
- receivedAmount,
57
- error
58
- };
59
- return preview2;
90
+ return claimed;
91
+ }
92
+ function repayFromClaim(post, claimToken, convert, amount) {
93
+ const spent = import_common_utils.BigIntMath.min(amount, post.balances.getOrZero(claimToken));
94
+ if (spent <= 0n) {
95
+ return;
60
96
  }
61
- const collateralWithdrawn = new import_sdk.AssetsMap();
62
- const repayFromClaim = (amount) => {
63
- const available = post.balances.getOrZero(request.claimToken);
64
- const spent = amount > available ? available : amount;
65
- if (spent <= 0n) {
66
- return;
67
- }
68
- const received = safeConvert(request.claimToken, post.underlying, spent);
69
- post.balances.dec(request.claimToken, spent);
70
- post.balances.inc(post.underlying, received);
71
- post.repay(received);
97
+ const received = convert(claimToken, post.underlying, spent);
98
+ post.balances.dec(claimToken, spent);
99
+ post.balances.inc(post.underlying, received);
100
+ post.repay(received);
101
+ }
102
+ function totalValueInUnderlying(post, convert, dust) {
103
+ return post.balances.sum(
104
+ (token, balance) => balance > dust ? convert(token, post.underlying, balance) : 0n
105
+ );
106
+ }
107
+ function buildClosePreview(post, converter) {
108
+ const totalValue = totalValueInUnderlying(post, converter.convert, 0n);
109
+ return {
110
+ operation: "CloseCreditAccount",
111
+ permanent: false,
112
+ creditManager: post.creditManager,
113
+ creditAccount: post.creditAccount,
114
+ receivedAmount: import_common_utils.BigIntMath.max(totalValue - post.totalDebt, 0n),
115
+ error: converter.error
72
116
  };
73
- if (intent?.type === "DECREASE_LEVERAGE") {
74
- repayFromClaim(claimed);
75
- } else if (intent?.type === "WITHDRAW_COLLATERAL") {
76
- const running = post.balances.getOrZero(intent.withdrawToken);
77
- const withdrawn = intent.withdrawAmount > running ? running : intent.withdrawAmount;
78
- if (withdrawn > 0n) {
79
- post.balances.dec(intent.withdrawToken, withdrawn);
80
- collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
81
- }
82
- const remainingClaim = (0, import_viem.isAddressEqual)(intent.withdrawToken, request.claimToken) && claimed > withdrawn ? claimed - withdrawn : claimed;
83
- repayFromClaim(remainingClaim);
84
- }
85
- const totalValue = post.balances.sum(
86
- (token, balance) => balance > import_types.PREVIEW_DUST ? safeConvert(token, post.underlying, balance) : 0n
117
+ }
118
+ function buildAdjustPreview(post, before, collateralWithdrawn, converter) {
119
+ const totalValue = totalValueInUnderlying(
120
+ post,
121
+ converter.convert,
122
+ import_types.PREVIEW_DUST
87
123
  );
88
- const preview = {
124
+ return {
89
125
  operation: "AdjustCreditAccount",
90
126
  creditManager: post.creditManager,
91
127
  creditAccount: post.creditAccount,
@@ -101,9 +137,8 @@ function buildDelayedPreview(state, before, detected, convert) {
101
137
  quotasChange: post.quotas.difference(before.quotas).toAssets(),
102
138
  assets: post.balances.toAssets(import_types.PREVIEW_DUST),
103
139
  assetsChange: post.balances.difference(before.balances).toAssets(import_types.PREVIEW_DUST),
104
- error
140
+ error: converter.error
105
141
  };
106
- return preview;
107
142
  }
108
143
  // Annotate the CommonJS export names for ESM import in node:
109
144
  0 && (module.exports = {
@@ -1,71 +1,107 @@
1
1
  import { isAddressEqual } from "viem";
2
+ import { BigIntMath } from "../../common-utils/index.js";
2
3
  import { AssetsMap } from "../../sdk/index.js";
3
4
  import {
4
5
  ERROR_UNPRICEABLE_TOKEN,
5
6
  PREVIEW_DUST
6
7
  } from "./types.js";
7
- function buildDelayedPreview(state, before, detected, convert) {
8
+ function buildDelayedPreview(afterInstant, before, detected, convert) {
8
9
  const { request, intent } = detected;
9
- const post = state.clone();
10
+ const post = afterInstant.clone();
11
+ const converter = makeSafeConverter(convert);
12
+ const claimed = applyClaim(post, request);
13
+ const collateralWithdrawn = new AssetsMap();
14
+ switch (intent?.type) {
15
+ case "CLOSE_ACCOUNT":
16
+ return buildClosePreview(post, converter);
17
+ case "DECREASE_LEVERAGE":
18
+ repayFromClaim(post, request.claimToken, converter.convert, claimed);
19
+ break;
20
+ case "WITHDRAW_COLLATERAL": {
21
+ const withdrawn = BigIntMath.min(
22
+ intent.withdrawAmount,
23
+ post.balances.getOrZero(intent.withdrawToken)
24
+ );
25
+ if (withdrawn > 0n) {
26
+ post.balances.dec(intent.withdrawToken, withdrawn);
27
+ collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
28
+ }
29
+ const claimSpentOnWithdrawal = isAddressEqual(
30
+ intent.withdrawToken,
31
+ request.claimToken
32
+ ) ? withdrawn : 0n;
33
+ repayFromClaim(
34
+ post,
35
+ request.claimToken,
36
+ converter.convert,
37
+ BigIntMath.max(claimed - claimSpentOnWithdrawal, 0n)
38
+ );
39
+ break;
40
+ }
41
+ default:
42
+ break;
43
+ }
44
+ return buildAdjustPreview(post, before, collateralWithdrawn, converter);
45
+ }
46
+ function makeSafeConverter(convert) {
10
47
  let error;
11
- const safeConvert = (token, to, amount) => {
12
- try {
13
- return convert(token, to, amount);
14
- } catch {
15
- error ??= {
16
- code: ERROR_UNPRICEABLE_TOKEN,
17
- message: `cannot price token ${token}`
18
- };
19
- return 0n;
48
+ return {
49
+ convert: (token, to, amount) => {
50
+ try {
51
+ return convert(token, to, amount);
52
+ } catch {
53
+ error ??= {
54
+ code: ERROR_UNPRICEABLE_TOKEN,
55
+ message: `cannot price token ${token}`
56
+ };
57
+ return 0n;
58
+ }
59
+ },
60
+ get error() {
61
+ return error;
20
62
  }
21
63
  };
64
+ }
65
+ function applyClaim(post, request) {
22
66
  const claimed = post.balances.getOrZero(request.phantomToken);
23
67
  post.balances.upsert(request.phantomToken, 0n);
24
68
  post.quotas.upsert(request.phantomToken, 0n);
25
69
  post.balances.inc(request.claimToken, claimed);
26
- if (intent?.type === "CLOSE_ACCOUNT") {
27
- const totalValue2 = post.balances.sum(
28
- (token, balance) => balance > 0n ? safeConvert(token, post.underlying, balance) : 0n
29
- );
30
- const receivedAmount = totalValue2 > post.totalDebt ? totalValue2 - post.totalDebt : 0n;
31
- const preview2 = {
32
- operation: "CloseCreditAccount",
33
- permanent: true,
34
- creditManager: post.creditManager,
35
- creditAccount: post.creditAccount,
36
- receivedAmount,
37
- error
38
- };
39
- return preview2;
70
+ return claimed;
71
+ }
72
+ function repayFromClaim(post, claimToken, convert, amount) {
73
+ const spent = BigIntMath.min(amount, post.balances.getOrZero(claimToken));
74
+ if (spent <= 0n) {
75
+ return;
40
76
  }
41
- const collateralWithdrawn = new AssetsMap();
42
- const repayFromClaim = (amount) => {
43
- const available = post.balances.getOrZero(request.claimToken);
44
- const spent = amount > available ? available : amount;
45
- if (spent <= 0n) {
46
- return;
47
- }
48
- const received = safeConvert(request.claimToken, post.underlying, spent);
49
- post.balances.dec(request.claimToken, spent);
50
- post.balances.inc(post.underlying, received);
51
- post.repay(received);
77
+ const received = convert(claimToken, post.underlying, spent);
78
+ post.balances.dec(claimToken, spent);
79
+ post.balances.inc(post.underlying, received);
80
+ post.repay(received);
81
+ }
82
+ function totalValueInUnderlying(post, convert, dust) {
83
+ return post.balances.sum(
84
+ (token, balance) => balance > dust ? convert(token, post.underlying, balance) : 0n
85
+ );
86
+ }
87
+ function buildClosePreview(post, converter) {
88
+ const totalValue = totalValueInUnderlying(post, converter.convert, 0n);
89
+ return {
90
+ operation: "CloseCreditAccount",
91
+ permanent: false,
92
+ creditManager: post.creditManager,
93
+ creditAccount: post.creditAccount,
94
+ receivedAmount: BigIntMath.max(totalValue - post.totalDebt, 0n),
95
+ error: converter.error
52
96
  };
53
- if (intent?.type === "DECREASE_LEVERAGE") {
54
- repayFromClaim(claimed);
55
- } else if (intent?.type === "WITHDRAW_COLLATERAL") {
56
- const running = post.balances.getOrZero(intent.withdrawToken);
57
- const withdrawn = intent.withdrawAmount > running ? running : intent.withdrawAmount;
58
- if (withdrawn > 0n) {
59
- post.balances.dec(intent.withdrawToken, withdrawn);
60
- collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
61
- }
62
- const remainingClaim = isAddressEqual(intent.withdrawToken, request.claimToken) && claimed > withdrawn ? claimed - withdrawn : claimed;
63
- repayFromClaim(remainingClaim);
64
- }
65
- const totalValue = post.balances.sum(
66
- (token, balance) => balance > PREVIEW_DUST ? safeConvert(token, post.underlying, balance) : 0n
97
+ }
98
+ function buildAdjustPreview(post, before, collateralWithdrawn, converter) {
99
+ const totalValue = totalValueInUnderlying(
100
+ post,
101
+ converter.convert,
102
+ PREVIEW_DUST
67
103
  );
68
- const preview = {
104
+ return {
69
105
  operation: "AdjustCreditAccount",
70
106
  creditManager: post.creditManager,
71
107
  creditAccount: post.creditAccount,
@@ -81,9 +117,8 @@ function buildDelayedPreview(state, before, detected, convert) {
81
117
  quotasChange: post.quotas.difference(before.quotas).toAssets(),
82
118
  assets: post.balances.toAssets(PREVIEW_DUST),
83
119
  assetsChange: post.balances.difference(before.balances).toAssets(PREVIEW_DUST),
84
- error
120
+ error: converter.error
85
121
  };
86
- return preview;
87
122
  }
88
123
  export {
89
124
  buildDelayedPreview
@@ -31,11 +31,12 @@ export type ConvertFn = (token: Address, to: Address, amount: bigint) => bigint;
31
31
  *
32
32
  * The changes (`debtChange`, `quotasChange`, `assetsChange`) are reported
33
33
  * relative to the account state before the whole transaction, not the
34
- * post-instant state: to the user the delayed preview answers "where will
34
+ * post-instant-part state: to the user the delayed preview answers "where will
35
35
  * the account end up compared to now", so the transient phantom token
36
36
  * (minted by the instant part, burned by the claim) nets out to nothing.
37
37
  *
38
- * @param state - Account state after the instant part of the transaction.
38
+ * @param afterInstant - Account state after the instant part of the
39
+ * transaction.
39
40
  * @param before - Account state before the transaction (the diff base).
40
41
  */
41
- export declare function buildDelayedPreview(state: CreditAccountState, before: CreditAccountState, detected: DetectedDelayedOperation, convert: ConvertFn): InstantOperationPreview;
42
+ export declare function buildDelayedPreview(afterInstant: CreditAccountState, before: CreditAccountState, detected: DetectedDelayedOperation, convert: ConvertFn): InstantOperationPreview;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "14.12.0-next.30",
3
+ "version": "14.12.0-next.31",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "repository": {