@gearbox-protocol/sdk 14.12.0-next.21 → 14.12.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.
Files changed (53) hide show
  1. package/dist/cjs/abi/IWithdrawalCompressorV313.js +2 -1
  2. package/dist/cjs/abi/compressors/withdrawalCompressor.js +2 -1
  3. package/dist/cjs/plugins/delayed-withdrawal/DelayedWithdrawalPlugin.js +1 -5
  4. package/dist/cjs/preview/preview/applyInnerOperations.js +83 -58
  5. package/dist/cjs/preview/preview/applyQuotaChanges.js +43 -0
  6. package/dist/cjs/preview/preview/errors.js +0 -16
  7. package/dist/cjs/preview/preview/index.js +2 -0
  8. package/dist/cjs/preview/preview/previewAdjustCreditAccount.js +19 -8
  9. package/dist/cjs/preview/preview/previewCloseOrRepayCreditAccount.js +18 -7
  10. package/dist/cjs/preview/preview/previewOpenCreditAccount.js +18 -6
  11. package/dist/cjs/preview/preview/types.js +30 -0
  12. package/dist/cjs/preview/preview/unwrapNativeCollateral.js +10 -4
  13. package/dist/cjs/sdk/OnchainSDK.js +3 -6
  14. package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +45 -37
  15. package/dist/cjs/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +14 -22
  16. package/dist/cjs/sdk/accounts/withdrawal-compressor/addresses.js +6 -18
  17. package/dist/cjs/sdk/accounts/withdrawal-compressor/createWithdrawalCompressor.js +3 -5
  18. package/dist/esm/abi/IWithdrawalCompressorV313.js +2 -1
  19. package/dist/esm/abi/compressors/withdrawalCompressor.js +2 -1
  20. package/dist/esm/plugins/delayed-withdrawal/DelayedWithdrawalPlugin.js +2 -9
  21. package/dist/esm/preview/preview/applyInnerOperations.js +90 -59
  22. package/dist/esm/preview/preview/applyQuotaChanges.js +19 -0
  23. package/dist/esm/preview/preview/errors.js +0 -15
  24. package/dist/esm/preview/preview/index.js +1 -0
  25. package/dist/esm/preview/preview/previewAdjustCreditAccount.js +20 -8
  26. package/dist/esm/preview/preview/previewCloseOrRepayCreditAccount.js +18 -7
  27. package/dist/esm/preview/preview/previewOpenCreditAccount.js +20 -6
  28. package/dist/esm/preview/preview/types.js +16 -0
  29. package/dist/esm/preview/preview/unwrapNativeCollateral.js +12 -4
  30. package/dist/esm/sdk/OnchainSDK.js +3 -6
  31. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +45 -37
  32. package/dist/esm/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +14 -22
  33. package/dist/esm/sdk/accounts/withdrawal-compressor/addresses.js +6 -18
  34. package/dist/esm/sdk/accounts/withdrawal-compressor/createWithdrawalCompressor.js +3 -5
  35. package/dist/types/abi/IWithdrawalCompressorV313.d.ts +4 -0
  36. package/dist/types/abi/compressors/withdrawalCompressor.d.ts +4 -0
  37. package/dist/types/permissionless/bindings/compressors/withdrawal-compressor.d.ts +4 -0
  38. package/dist/types/preview/preview/applyInnerOperations.d.ts +8 -33
  39. package/dist/types/preview/preview/applyQuotaChanges.d.ts +24 -0
  40. package/dist/types/preview/preview/errors.d.ts +0 -12
  41. package/dist/types/preview/preview/index.d.ts +1 -0
  42. package/dist/types/preview/preview/previewAdjustCreditAccount.d.ts +1 -1
  43. package/dist/types/preview/preview/previewOpenCreditAccount.d.ts +1 -1
  44. package/dist/types/preview/preview/types.d.ts +81 -0
  45. package/dist/types/preview/preview/unwrapNativeCollateral.d.ts +19 -4
  46. package/dist/types/sdk/OnchainSDK.d.ts +3 -6
  47. package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +5 -1
  48. package/dist/types/sdk/accounts/types.d.ts +32 -3
  49. package/dist/types/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.d.ts +4 -0
  50. package/dist/types/sdk/accounts/withdrawal-compressor/addresses.d.ts +1 -2
  51. package/dist/types/sdk/accounts/withdrawal-compressor/createWithdrawalCompressor.d.ts +2 -4
  52. package/dist/types/sdk/accounts/withdrawal-compressor/types.d.ts +7 -0
  53. package/package.json +1 -1
@@ -6,6 +6,9 @@ import {
6
6
  applyInnerOperations,
7
7
  makeInnerOperationsState
8
8
  } from "./applyInnerOperations.js";
9
+ import {
10
+ ERROR_UNPRICEABLE_TOKEN
11
+ } from "./types.js";
9
12
  import { unwrapNativeCollateral } from "./unwrapNativeCollateral.js";
10
13
  function previewOpenCreditAccount(input, operation) {
11
14
  const { sdk, value = 0n } = input;
@@ -13,15 +16,25 @@ function previewOpenCreditAccount(input, operation) {
13
16
  operation.creditManager
14
17
  );
15
18
  const state = makeInnerOperationsState();
16
- applyInnerOperations(sdk, operation.multicall, state);
17
- const collateralValue = state.collateralAdded.sum(
18
- (token, balance) => market.priceOracle.convert(token, market.underlying, balance)
19
- );
20
- const collateral = unwrapNativeCollateral(
19
+ let error = applyInnerOperations(sdk, operation.multicall, state);
20
+ let priceError;
21
+ const collateralValue = state.collateralAdded.sum((token, balance) => {
22
+ try {
23
+ return market.priceOracle.convert(token, market.underlying, balance);
24
+ } catch {
25
+ priceError ??= {
26
+ code: ERROR_UNPRICEABLE_TOKEN,
27
+ message: `cannot price token ${token}`
28
+ };
29
+ return 0n;
30
+ }
31
+ });
32
+ const { assets: collateral, error: unwrapError } = unwrapNativeCollateral(
21
33
  state.collateralAdded.toAssets(),
22
34
  value,
23
35
  sdk.addressProvider.getAddress(AP_WETH_TOKEN, NO_VERSION)
24
36
  );
37
+ error ??= unwrapError ?? priceError;
25
38
  const assets = state.balances.toAssets(1n);
26
39
  return {
27
40
  operation: operation.operation,
@@ -32,7 +45,8 @@ function previewOpenCreditAccount(input, operation) {
32
45
  debt: state.debt,
33
46
  // On opening, initial quotas are zero, so the raw changes are the quotas.
34
47
  quotas: state.quotaChanges,
35
- assets
48
+ assets,
49
+ error
36
50
  };
37
51
  }
38
52
  function inferTargetAsset(multicall, balances) {
@@ -0,0 +1,16 @@
1
+ const ERROR_MALFORMED_BRACKET = 1001;
2
+ const ERROR_ADAPTER_CALL_OUTSIDE_BRACKET = 1002;
3
+ const ERROR_NON_ADAPTER_CALL_IN_BRACKET = 1003;
4
+ const ERROR_UNPREVIEWABLE_ADAPTER_CALL = 1004;
5
+ const ERROR_UNPREVIEWABLE_RWA_WRAP_UNWRAP = 1005;
6
+ const ERROR_INVALID_TRANSACTION_VALUE = 1006;
7
+ const ERROR_UNPRICEABLE_TOKEN = 2001;
8
+ export {
9
+ ERROR_ADAPTER_CALL_OUTSIDE_BRACKET,
10
+ ERROR_INVALID_TRANSACTION_VALUE,
11
+ ERROR_MALFORMED_BRACKET,
12
+ ERROR_NON_ADAPTER_CALL_IN_BRACKET,
13
+ ERROR_UNPREVIEWABLE_ADAPTER_CALL,
14
+ ERROR_UNPREVIEWABLE_RWA_WRAP_UNWRAP,
15
+ ERROR_UNPRICEABLE_TOKEN
16
+ };
@@ -1,20 +1,28 @@
1
1
  import { AssetsMap, NATIVE_ADDRESS } from "../../sdk/index.js";
2
- import { InvalidTransactionValueError } from "./errors.js";
2
+ import {
3
+ ERROR_INVALID_TRANSACTION_VALUE
4
+ } from "./types.js";
3
5
  function unwrapNativeCollateral(collateral, nativeAmount, wethToken) {
4
6
  if (nativeAmount === 0n) {
5
- return collateral;
7
+ return { assets: collateral };
6
8
  }
7
9
  const balances = new AssetsMap(collateral);
8
10
  const wethBalance = balances.get(wethToken) ?? 0n;
9
11
  if (wethBalance < nativeAmount) {
10
- throw new InvalidTransactionValueError(nativeAmount, wethBalance);
12
+ return {
13
+ assets: collateral,
14
+ error: {
15
+ code: ERROR_INVALID_TRANSACTION_VALUE,
16
+ message: `transaction value ${nativeAmount} exceeds WETH collateral ${wethBalance}`
17
+ }
18
+ };
11
19
  }
12
20
  balances.upsert(
13
21
  wethToken,
14
22
  wethBalance === nativeAmount ? void 0 : wethBalance - nativeAmount
15
23
  );
16
24
  balances.inc(NATIVE_ADDRESS, nativeAmount);
17
- return balances.toAssets();
25
+ return { assets: balances.toAssets() };
18
26
  }
19
27
  export {
20
28
  unwrapNativeCollateral
@@ -538,13 +538,10 @@ class OnchainSDK extends ChainContractsRegister {
538
538
  /**
539
539
  * Lazily returns a withdrawal compressor contract for the current chain.
540
540
  *
541
- * @param version - Desired compressor version; when omitted, the latest
542
- * version supported on the current chain is used.
543
- * @throws If no withdrawal compressor of the given version is supported
544
- * on the current chain.
541
+ * @throws If no withdrawal compressor is supported on the current chain.
545
542
  **/
546
- withdrawalCompressor(version) {
547
- return createWithdrawalCompressor(this, version);
543
+ get withdrawalCompressor() {
544
+ return createWithdrawalCompressor(this);
548
545
  }
549
546
  }
550
547
  export {
@@ -782,8 +782,7 @@ class CreditAccountsServiceV310 extends SDKConstruct {
782
782
  token,
783
783
  intent
784
784
  }) {
785
- const compressor = this.sdk.withdrawalCompressor();
786
- return compressor.getWithdrawalRequestResult(
785
+ return this.sdk.withdrawalCompressor.getWithdrawalRequestResult(
787
786
  creditAccount,
788
787
  token,
789
788
  amount,
@@ -796,8 +795,7 @@ class CreditAccountsServiceV310 extends SDKConstruct {
796
795
  async getPendingWithdrawals({
797
796
  creditAccount
798
797
  }) {
799
- const compressor = this.sdk.withdrawalCompressor();
800
- const { claimable, pending } = await compressor.getCurrentWithdrawals(creditAccount);
798
+ const { claimable, pending } = await this.sdk.withdrawalCompressor.getCurrentWithdrawals(creditAccount);
801
799
  return {
802
800
  claimableNow: claimable,
803
801
  pending
@@ -839,6 +837,45 @@ class CreditAccountsServiceV310 extends SDKConstruct {
839
837
  };
840
838
  return [storeExpectedBalances, ...preview.requestCalls, compareBalances];
841
839
  }
840
+ /**
841
+ * {@inheritDoc ICreditAccountsService.assembleClaimDelayedCalls}
842
+ **/
843
+ assembleClaimDelayedCalls({
844
+ creditFacade,
845
+ claimableNow
846
+ }) {
847
+ const record = claimableNow.outputs.reduce(
848
+ (acc, o) => {
849
+ const token = o.token.toLowerCase();
850
+ acc[token] = (acc[token] || 0n) + o.amount;
851
+ return acc;
852
+ },
853
+ {}
854
+ );
855
+ const balances = Object.entries(record).filter(([, a]) => a > 10n);
856
+ const storeExpectedBalances = {
857
+ target: creditFacade,
858
+ callData: encodeFunctionData({
859
+ abi: iCreditFacadeMulticallV310Abi,
860
+ functionName: "storeExpectedBalances",
861
+ args: [
862
+ balances.map(([token, amount]) => ({
863
+ token,
864
+ amount: amount > 10n ? amount - 10n : 0n
865
+ }))
866
+ ]
867
+ })
868
+ };
869
+ const compareBalances = {
870
+ target: creditFacade,
871
+ callData: encodeFunctionData({
872
+ abi: iCreditFacadeMulticallV310Abi,
873
+ functionName: "compareBalances",
874
+ args: []
875
+ })
876
+ };
877
+ return [storeExpectedBalances, ...claimableNow.claimCalls, compareBalances];
878
+ }
842
879
  /**
843
880
  * {@inheritDoc ICreditAccountsService.startDelayedWithdrawal}
844
881
  **/
@@ -882,44 +919,15 @@ class CreditAccountsServiceV310 extends SDKConstruct {
882
919
  const cm = this.sdk.marketRegister.findCreditManager(
883
920
  creditAccount.creditManager
884
921
  );
885
- const record = claimableNow.outputs.reduce(
886
- (acc, o) => {
887
- const token = o.token.toLowerCase();
888
- acc[token] = (acc[token] || 0n) + o.amount;
889
- return acc;
890
- },
891
- {}
892
- );
893
- const balances = Object.entries(record).filter(([, a]) => a > 10n);
894
- const storeExpectedBalances = {
895
- target: cm.creditFacade.address,
896
- callData: encodeFunctionData({
897
- abi: iCreditFacadeMulticallV310Abi,
898
- functionName: "storeExpectedBalances",
899
- args: [
900
- balances.map(([token, amount]) => ({
901
- token,
902
- amount: amount > 10n ? amount - 10n : 0n
903
- }))
904
- ]
905
- })
906
- };
907
- const compareBalances = {
908
- target: cm.creditFacade.address,
909
- callData: encodeFunctionData({
910
- abi: iCreditFacadeMulticallV310Abi,
911
- functionName: "compareBalances",
912
- args: []
913
- })
914
- };
915
922
  const quotaCalls = zeroDebt ? [] : this.#prepareUpdateQuotas(cm.creditFacade.address, {
916
923
  minQuota,
917
924
  averageQuota
918
925
  });
919
926
  const operationCalls = [
920
- storeExpectedBalances,
921
- ...claimableNow.claimCalls,
922
- compareBalances,
927
+ ...this.assembleClaimDelayedCalls({
928
+ creditFacade: cm.creditFacade.address,
929
+ claimableNow
930
+ }),
923
931
  ...quotaCalls
924
932
  ];
925
933
  const calls = zeroDebt ? operationCalls : await this.#prependPriceUpdates(
@@ -84,7 +84,7 @@ class AbstractWithdrawalCompressorContract extends BaseContract {
84
84
  claimable: claimable.map(
85
85
  (w) => toClaimableWithdrawal(w, creditManager, this.version >= 313)
86
86
  ),
87
- pending: pending.map(toPendingWithdrawal).sort((a, b) => a.claimableAt < b.claimableAt ? -1 : 1)
87
+ pending: pending.map((w) => toPendingWithdrawal(w, creditManager, this.version >= 313)).sort((a, b) => a.claimableAt < b.claimableAt ? -1 : 1)
88
88
  };
89
89
  }
90
90
  /**
@@ -104,8 +104,8 @@ class AbstractWithdrawalCompressorContract extends BaseContract {
104
104
  return {
105
105
  token: resp.token,
106
106
  amountIn: resp.amountIn,
107
- outputs: resp.outputs.map(toWithdrawalOutput),
108
- requestCalls: resp.requestCalls.map(toMultiCall),
107
+ outputs: [...resp.outputs],
108
+ requestCalls: [...resp.requestCalls],
109
109
  claimableAt: resp.claimableAt
110
110
  };
111
111
  }
@@ -157,21 +157,8 @@ class AbstractWithdrawalCompressorContract extends BaseContract {
157
157
  ]);
158
158
  }
159
159
  }
160
- function toWithdrawalOutput(o) {
161
- return { token: o.token, isDelayed: o.isDelayed, amount: o.amount };
162
- }
163
- function toMultiCall(c) {
164
- return { target: c.target, callData: c.callData };
165
- }
166
160
  function toWithdrawableAsset(a, creditManager) {
167
- return {
168
- creditManager,
169
- token: a.token,
170
- withdrawalPhantomToken: a.withdrawalPhantomToken,
171
- underlying: a.underlying,
172
- withdrawalLength: a.withdrawalLength,
173
- maxWithdrawals: a.maxWithdrawals
174
- };
161
+ return { creditManager, ...a };
175
162
  }
176
163
  function toClaimableWithdrawal(w, creditManager, decodeIntent) {
177
164
  let intent;
@@ -182,17 +169,22 @@ function toClaimableWithdrawal(w, creditManager, decodeIntent) {
182
169
  token: w.token,
183
170
  withdrawalPhantomToken: w.withdrawalPhantomToken,
184
171
  withdrawalTokenSpent: w.withdrawalTokenSpent,
185
- outputs: w.outputs.map(toWithdrawalOutput),
186
- claimCalls: w.claimCalls.map(toMultiCall),
172
+ outputs: [...w.outputs],
173
+ claimCalls: [...w.claimCalls],
187
174
  intent
188
175
  };
189
176
  }
190
- function toPendingWithdrawal(w) {
177
+ function toPendingWithdrawal(w, creditManager, decodeIntent) {
178
+ let intent;
179
+ if (decodeIntent && w.extraData && w.extraData !== "0x") {
180
+ intent = { ...decodeDelayedIntent(w.extraData), creditManager };
181
+ }
191
182
  return {
192
183
  token: w.token,
193
184
  withdrawalPhantomToken: w.withdrawalPhantomToken,
194
- expectedOutputs: w.expectedOutputs.map(toWithdrawalOutput),
195
- claimableAt: w.claimableAt
185
+ expectedOutputs: [...w.expectedOutputs],
186
+ claimableAt: w.claimableAt,
187
+ intent
196
188
  };
197
189
  }
198
190
  export {
@@ -1,27 +1,15 @@
1
1
  const WITHDRAWAL_COMPRESSORS = {
2
2
  Mainnet: {
3
- 310: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
4
- 313: "0x9605D59E40963ADce8a6895Aa3Fa497320Ef3F3b"
3
+ address: "0x83e5AaC6590Cf9c6Dd323851a0D66fEc2Bc4F5A3",
4
+ version: 313
5
5
  },
6
6
  Monad: {
7
- 310: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023"
7
+ address: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
8
+ version: 310
8
9
  }
9
10
  };
10
- function getWithdrawalCompressorAddress(network, version) {
11
- const deployments = WITHDRAWAL_COMPRESSORS[network];
12
- if (!deployments) {
13
- return void 0;
14
- }
15
- if (version !== void 0) {
16
- const address2 = deployments[version];
17
- return address2 ? { address: address2, version } : void 0;
18
- }
19
- const latest = Object.keys(deployments).map(Number).sort((a, b) => b - a)[0];
20
- if (latest === void 0) {
21
- return void 0;
22
- }
23
- const address = deployments[latest];
24
- return address ? { address, version: latest } : void 0;
11
+ function getWithdrawalCompressorAddress(network) {
12
+ return WITHDRAWAL_COMPRESSORS[network];
25
13
  }
26
14
  export {
27
15
  getWithdrawalCompressorAddress
@@ -2,12 +2,10 @@ import { getWithdrawalCompressorAddress } from "./addresses.js";
2
2
  import { WithdrawalCompressorV310Contract } from "./WithdrawalCompressorV310Contract.js";
3
3
  import { WithdrawalCompressorV311Contract } from "./WithdrawalCompressorV311Contract.js";
4
4
  import { WithdrawalCompressorV313Contract } from "./WithdrawalCompressorV313Contract.js";
5
- function createWithdrawalCompressor(sdk, version) {
6
- const location = getWithdrawalCompressorAddress(sdk.networkType, version);
5
+ function createWithdrawalCompressor(sdk) {
6
+ const location = getWithdrawalCompressorAddress(sdk.networkType);
7
7
  if (!location) {
8
- throw new Error(
9
- `no withdrawal compressor${version ? ` v${version}` : ""} on ${sdk.networkType}`
10
- );
8
+ throw new Error(`no withdrawal compressor on ${sdk.networkType}`);
11
9
  }
12
10
  const cached = sdk.getContract(
13
11
  location.address
@@ -100,6 +100,10 @@ export declare const iWithdrawalCompressorV313Abi: readonly [{
100
100
  readonly name: "claimableAt";
101
101
  readonly type: "uint256";
102
102
  readonly internalType: "uint256";
103
+ }, {
104
+ readonly name: "extraData";
105
+ readonly type: "bytes";
106
+ readonly internalType: "bytes";
103
107
  }];
104
108
  }];
105
109
  readonly stateMutability: "view";
@@ -136,6 +136,10 @@ export declare const withdrawalCompressorAbi: readonly [{
136
136
  readonly name: "claimableAt";
137
137
  readonly type: "uint256";
138
138
  readonly internalType: "uint256";
139
+ }, {
140
+ readonly name: "extraData";
141
+ readonly type: "bytes";
142
+ readonly internalType: "bytes";
139
143
  }];
140
144
  }];
141
145
  readonly stateMutability: "view";
@@ -138,6 +138,10 @@ declare const abi: readonly [{
138
138
  readonly name: "claimableAt";
139
139
  readonly type: "uint256";
140
140
  readonly internalType: "uint256";
141
+ }, {
142
+ readonly name: "extraData";
143
+ readonly type: "bytes";
144
+ readonly internalType: "bytes";
141
145
  }];
142
146
  }];
143
147
  readonly stateMutability: "view";
@@ -1,6 +1,7 @@
1
1
  import { type SdkWithAdapters } from "../../plugins/adapters/index.js";
2
2
  import { type Asset, AssetsMap, type PluginsMap } from "../../sdk/index.js";
3
3
  import type { InnerOperation } from "../parse/index.js";
4
+ import { type OperationPreviewError } from "./types.js";
4
5
  /**
5
6
  * Running state threaded through a credit-facade multicall by
6
7
  * {@link applyInnerOperations}. Seeded by the caller:
@@ -37,8 +38,7 @@ export interface InnerOperationsState {
37
38
  /**
38
39
  * Raw `updateQuota` changes, one entry per op. Entries are relative signed
39
40
  * changes (with the `MIN_INT96` "disable" sentinel kept as-is), not final
40
- * quotas: folding them requires pre-state quotas, see
41
- * {@link applyQuotaChanges}.
41
+ * quotas: folding them requires pre-state quotas, see `applyQuotaChanges`.
42
42
  */
43
43
  quotaChanges: Asset[];
44
44
  }
@@ -48,37 +48,12 @@ export interface InnerOperationsState {
48
48
  export declare function makeInnerOperationsState(): InnerOperationsState;
49
49
  /**
50
50
  * Replays a credit-facade multicall over `state`, mutating it in place in
51
- * facade execution order. The result is the *minimal guaranteed* post-state:
52
- * exact deltas for explicit facade calls, exact leftovers for diff-style
53
- * adapter calls inside `storeExpectedBalances`/`compareBalances` brackets and
54
- * enforced minimums for bracket targets. Adapter calls outside a bracket are
55
- * ignored: nothing enforces their outcome on-chain (e.g. reward claims), so
56
- * their guaranteed balance change is zero.
51
+ * facade execution order. The result is the *minimal guaranteed* post-state.
57
52
  *
58
- * The exception is RWA wrap/unwrap calls emitted by
59
- * `CreditAccountsServiceV310`: out-of-bracket ERC4626 adapter calls whose
60
- * share token is an RWA underlying. Their outcome is essential to the preview
61
- * (the conversion between the market underlying and its asset); RWA
62
- * underlyings always convert 1-to-1 with their vault asset, so the conversion
63
- * is applied directly, see {@link applyRWAWrapUnwrap}.
53
+ * The function assumes that the call was generated by our frontend using
54
+ * router/withdrawal compressor, otherwise it returns an error, but still
55
+ * proceeds best-effort.
64
56
  *
65
- * @throws On malformed `storeExpectedBalances`/`compareBalances` brackets and
66
- * on bracketed calls to non-adapter targets.
57
+ * @returns `undefined` on success, the error on a malformed multicall.
67
58
  */
68
- export declare function applyInnerOperations<P extends PluginsMap>(sdk: SdkWithAdapters<P>, multicall: InnerOperation[], state: InnerOperationsState): void;
69
- /**
70
- * Applies raw `updateQuota` changes to the account's initial quotas.
71
- *
72
- * Each change is applied sequentially: `MIN_INT96` disables the quota, other
73
- * changes are added to the running quota with the result clamped at zero
74
- * (quotas cannot go negative on-chain).
75
- *
76
- * @param initialQuotas - Per-token quotas before the operation.
77
- * @param changes - Raw changes recorded by {@link applyInnerOperations}.
78
- * @returns `quotas` - final non-zero per-token quotas; `quotasChange` -
79
- * applied (post-clamp) per-token deltas, non-zero entries only.
80
- */
81
- export declare function applyQuotaChanges(initialQuotas: AssetsMap, changes: Asset[]): {
82
- quotas: Asset[];
83
- quotasChange: Asset[];
84
- };
59
+ export declare function applyInnerOperations<P extends PluginsMap>(sdk: SdkWithAdapters<P>, multicall: InnerOperation[], state: InnerOperationsState): OperationPreviewError | undefined;
@@ -0,0 +1,24 @@
1
+ import { type Asset, type AssetsMap } from "../../sdk/index.js";
2
+ export interface ApplyQuotaChangesResult {
3
+ /**
4
+ * Final non-zero per-token quotas.
5
+ */
6
+ quotas: Asset[];
7
+ /**
8
+ * Applied (post-clamp) per-token deltas, non-zero entries only.
9
+ */
10
+ quotasChange: Asset[];
11
+ }
12
+ /**
13
+ * Applies raw `updateQuota` changes to the account's initial quotas.
14
+ *
15
+ * Each change is applied sequentially: `MIN_INT96` disables the quota, other
16
+ * changes are added to the running quota with the result clamped at zero
17
+ * (quotas cannot go negative on-chain).
18
+ *
19
+ * @param initialQuotas - Per-token quotas before the operation.
20
+ * @param changes - Raw changes recorded by `applyInnerOperations`.
21
+ * @returns `quotas` - final non-zero per-token quotas; `quotasChange` -
22
+ * applied (post-clamp) per-token deltas, non-zero entries only.
23
+ */
24
+ export declare function applyQuotaChanges(initialQuotas: AssetsMap, changes: Asset[]): ApplyQuotaChangesResult;
@@ -1,15 +1,3 @@
1
- /**
2
- * Thrown when a transaction's attached native value (`msg.value`) does not fit
3
- * into the WETH collateral declared by the multicall: such a transaction is
4
- * malformed and would not execute successfully.
5
- */
6
- export declare class InvalidTransactionValueError extends Error {
7
- /** Transaction `msg.value`. */
8
- readonly value: bigint;
9
- /** Amount of wrapped native token added as collateral. */
10
- readonly wethCollateral: bigint;
11
- constructor(value: bigint, wethCollateral: bigint);
12
- }
13
1
  /**
14
2
  * Thrown by `previewOperation` for parsed operations it cannot preview yet.
15
3
  * Currently only pool operations and credit account opening are supported.
@@ -1,4 +1,5 @@
1
1
  export * from "./applyInnerOperations.js";
2
+ export * from "./applyQuotaChanges.js";
2
3
  export * from "./detectCloseOrRepay.js";
3
4
  export * from "./errors.js";
4
5
  export * from "./previewAdjustCreditAccount.js";
@@ -1,7 +1,7 @@
1
1
  import { type PluginsMap } from "../../sdk/index.js";
2
2
  import type { MulticallOperation, RWAMulticallOperation } from "../parse/index.js";
3
3
  import type { PreviewOperationInput, PreviewOperationOptions } from "../types.js";
4
- import type { AdjustCreditAccountPreview } from "./types.js";
4
+ import { type AdjustCreditAccountPreview } from "./types.js";
5
5
  /**
6
6
  * Previews a `multicall`/`botMulticall` operation on an existing credit
7
7
  * account: fetches the account's pre-state (unless provided via options),
@@ -1,5 +1,5 @@
1
1
  import { type PluginsMap } from "../../sdk/index.js";
2
2
  import type { OpenCreditAccountOperation, RWAOpenCreditAccountOperation } from "../parse/index.js";
3
3
  import type { PreviewOperationInput } from "../types.js";
4
- import type { OpenCreditAccountPreview } from "./types.js";
4
+ import { type OpenCreditAccountPreview } from "./types.js";
5
5
  export declare function previewOpenCreditAccount<P extends PluginsMap>(input: PreviewOperationInput<P>, operation: OpenCreditAccountOperation | RWAOpenCreditAccountOperation): OpenCreditAccountPreview;
@@ -1,6 +1,58 @@
1
1
  import type { Address } from "viem";
2
2
  import type { Asset } from "../../sdk/index.js";
3
3
  import type { PoolOperationType } from "../parse/index.js";
4
+ /**
5
+ * Broken `storeExpectedBalances`/`compareBalances` bracket structure:
6
+ * `storeExpectedBalances` without a matching `compareBalances`, more than one
7
+ * bracket, or `compareBalances` without a preceding `storeExpectedBalances`.
8
+ * We expect transactions that were generated by our frontend using router/withdrawal compressor
9
+ **/
10
+ export declare const ERROR_MALFORMED_BRACKET = 1001;
11
+ /**
12
+ * Adapter call outside a `storeExpectedBalances`/`compareBalances` bracket
13
+ * We expect transactions that were generated by our frontend using router/withdrawal compressor,
14
+ **/
15
+ export declare const ERROR_ADAPTER_CALL_OUTSIDE_BRACKET = 1002;
16
+ /**
17
+ * Bracketed call whose target is not an adapter (or adapter that is not known to the SDK)
18
+ **/
19
+ export declare const ERROR_NON_ADAPTER_CALL_IN_BRACKET = 1003;
20
+ /**
21
+ * Bracketed adapter call cannot be replayed (undecodable/unsupported calldata)
22
+ **/
23
+ export declare const ERROR_UNPREVIEWABLE_ADAPTER_CALL = 1004;
24
+ /**
25
+ * Out-of-bracket RWA wrap/unwrap calldata cannot be decoded
26
+ **/
27
+ export declare const ERROR_UNPREVIEWABLE_RWA_WRAP_UNWRAP = 1005;
28
+ /**
29
+ * `msg.value` does not fit into the declared WETH collateral
30
+ * Transactions can have arbitrary value, but the ones that we create
31
+ * using our frontend should have a value that fits into the declared WETH collateral.
32
+ **/
33
+ export declare const ERROR_INVALID_TRANSACTION_VALUE = 1006;
34
+ /** A token in the preview could not be priced by the oracle */
35
+ export declare const ERROR_UNPRICEABLE_TOKEN = 2001;
36
+ /**
37
+ * Non-throwing preview failure. When set on a preview, all fields are still
38
+ * computed best-effort, but some of them may be unreliable.
39
+ */
40
+ export interface OperationPreviewError {
41
+ /**
42
+ * Numeric http-style error code, see the `ERROR_*` constants:
43
+ * - 1xxx: the transaction is malformed (we expect transactions
44
+ * that were generated by our fromtend using router/withdrawal compressor)
45
+ * and fields derived from replayed balances
46
+ * may be unreliable;
47
+ * - 2xxx: the transaction may be fine, but the SDK could not fully
48
+ * evaluate the preview (e.g. a token could not be priced).
49
+ */
50
+ code: number;
51
+ /**
52
+ * Human-readable details of the specific failure
53
+ */
54
+ message: string;
55
+ }
4
56
  export interface PoolOperationPreview {
5
57
  operation: PoolOperationType;
6
58
  /**
@@ -27,6 +79,11 @@ export interface PoolOperationPreview {
27
79
  * (previewDeposit/previewRedeem).
28
80
  */
29
81
  tokenOut: Asset;
82
+ /**
83
+ * Set when preview encountered non-fatal errors, all fields are
84
+ * still computed best-effort
85
+ */
86
+ error?: OperationPreviewError;
30
87
  }
31
88
  export interface OpenCreditAccountPreview {
32
89
  operation: "OpenCreditAccount" | "RWAOpenCreditAccount";
@@ -64,6 +121,12 @@ export interface OpenCreditAccountPreview {
64
121
  * as estimated by router
65
122
  */
66
123
  assets: Asset[];
124
+ /**
125
+ * Set when preview encountered non-fatal errors, all fields are
126
+ * still computed best-effort, but derived fields (`assets`, `target`,
127
+ * `collateralValue`) may be unreliable in that case.
128
+ */
129
+ error?: OperationPreviewError;
67
130
  }
68
131
  export interface AdjustCreditAccountPreview {
69
132
  operation: "AdjustCreditAccount";
@@ -116,6 +179,12 @@ export interface AdjustCreditAccountPreview {
116
179
  * Assets after minus assets before
117
180
  */
118
181
  assetsChange: Asset[];
182
+ /**
183
+ * Set when preview encountered non-fatal errors, all fields are
184
+ * still computed best-effort, but derived fields (`assets`, `assetsChange`,
185
+ * `totalValue`) may be unreliable in that case.
186
+ */
187
+ error?: OperationPreviewError;
119
188
  }
120
189
  export interface CloseCreditAccountPreview {
121
190
  operation: "CloseCreditAccount";
@@ -139,6 +208,12 @@ export interface CloseCreditAccountPreview {
139
208
  * withdrawal)
140
209
  */
141
210
  receivedAmount: bigint;
211
+ /**
212
+ * Set when preview encountered non-fatal errors, all fields are
213
+ * still computed best-effort, but the
214
+ * balance-derived `receivedAmount` may be unreliable in that case.
215
+ */
216
+ error?: OperationPreviewError;
142
217
  }
143
218
  export interface RepayCreditAccountPreview {
144
219
  operation: "RepayCreditAccount";
@@ -173,6 +248,12 @@ export interface RepayCreditAccountPreview {
173
248
  * Total debt repaid: principal + accrued interest + fees, in underlying
174
249
  */
175
250
  debtRepaid: bigint;
251
+ /**
252
+ * Set when preview encountered non-fatal errors, all fields are
253
+ * still computed best-effort, but the
254
+ * balance-derived `collateralWithdrawn` may be unreliable in that case.
255
+ */
256
+ error?: OperationPreviewError;
176
257
  }
177
258
  /**
178
259
  * Result of previewing a raw operation calldata: currently pool operations and