@vultisig/core-chain 2.24.1 → 2.24.3

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 (32) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/amount/fromChainAmountExact.d.ts +28 -0
  3. package/dist/amount/fromChainAmountExact.d.ts.map +1 -0
  4. package/dist/amount/fromChainAmountExact.js +47 -0
  5. package/dist/amount/fromChainAmountExact.js.map +1 -0
  6. package/dist/amount/toChainAmount.d.ts.map +1 -1
  7. package/dist/amount/toChainAmount.js +25 -5
  8. package/dist/amount/toChainAmount.js.map +1 -1
  9. package/dist/chains/solana/assertSafeSolanaSwapInstructions.d.ts +96 -0
  10. package/dist/chains/solana/assertSafeSolanaSwapInstructions.d.ts.map +1 -0
  11. package/dist/chains/solana/assertSafeSolanaSwapInstructions.js +260 -0
  12. package/dist/chains/solana/assertSafeSolanaSwapInstructions.js.map +1 -0
  13. package/dist/swap/general/jupiter/api/getJupiterSwapQuote.d.ts.map +1 -1
  14. package/dist/swap/general/jupiter/api/getJupiterSwapQuote.js +9 -0
  15. package/dist/swap/general/jupiter/api/getJupiterSwapQuote.js.map +1 -1
  16. package/dist/swap/general/jupiter/api/jupiterFeeAta.d.ts +2 -1
  17. package/dist/swap/general/jupiter/api/jupiterFeeAta.d.ts.map +1 -1
  18. package/dist/swap/general/jupiter/api/jupiterFeeAta.js +7 -35
  19. package/dist/swap/general/jupiter/api/jupiterFeeAta.js.map +1 -1
  20. package/dist/swap/native/NativeSwapChain.d.ts +1 -0
  21. package/dist/swap/native/NativeSwapChain.d.ts.map +1 -1
  22. package/dist/swap/native/NativeSwapChain.js +1 -1
  23. package/dist/swap/native/NativeSwapChain.js.map +1 -1
  24. package/dist/swap/native/limitSwapMemo.d.ts.map +1 -1
  25. package/dist/swap/native/limitSwapMemo.js +39 -2
  26. package/dist/swap/native/limitSwapMemo.js.map +1 -1
  27. package/dist/swap/quote/findSwapQuote.d.ts +16 -3
  28. package/dist/swap/quote/findSwapQuote.d.ts.map +1 -1
  29. package/dist/swap/quote/findSwapQuote.js +32 -3
  30. package/dist/swap/quote/findSwapQuote.js.map +1 -1
  31. package/fixtures/jupiter-swap-transactions.json +30 -0
  32. package/package.json +12 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @vultisig/core-chain
2
2
 
3
+ ## 2.24.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1115](https://github.com/vultisig/vultisig-sdk/pull/1115) [`4483754`](https://github.com/vultisig/vultisig-sdk/commit/4483754748190fe25654de79fc12fba0edb73963) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Expand large scientific-notation numeric amounts before base-unit parsing.
8
+
9
+ ## 2.24.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [#1018](https://github.com/vultisig/vultisig-sdk/pull/1018) [`90070f3`](https://github.com/vultisig/vultisig-sdk/commit/90070f39be011821f7508c7ff094025861dce040) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - fix(swap): accept returned quote provider ids in `findSwapQuote.excludeProviders`
14
+
15
+ `findSwapQuote.excludeProviders` now accepts both display names (`CowSwap`, `KyberSwap`, `LiFi`) and returned quote provider ids (`cowswap`, `kyber`, `li.fi`) for general providers. Unknown exclude tokens now fail closed instead of silently leaving the provider eligible.
16
+
17
+ - [#1112](https://github.com/vultisig/vultisig-sdk/pull/1112) [`2c9d34e`](https://github.com/vultisig/vultisig-sdk/commit/2c9d34e0837f68d92769c7aefa566ffb1c0c52c7) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - fix(swap): resolve THORChain limit-swap destination chains via the swap-eligible chain set, not the LP-position map (THOR-04) — `getSupportedThorchainAssetChain` (`limitSwapMemo.ts`) resolved a THORChain asset-prefix (e.g. `SOL`, `NOBLE`) to a `Chain` via `lpChainMap`, a map scoped to the wallet's LP-position-display feature (`chains/cosmos/thor/lp/lpChainMap.ts`), not swap eligibility. Since neither Solana nor Noble has a THORChain LP pool, both were missing from that map, so a limit swap (`LIM=` memo) targeting either failed closed with "unsupported THORChain asset prefix" even though both are valid THORChain market-swap destinations (per THORChain's memo docs, `=` vs `=<` only changes execution behavior — price/queue/TTL — not the destination-chain universe). Fixed by unioning `lpChainMap` with `thorChainSwapEnabledChains` (`swap/native/NativeSwapChain.ts`, now exported) — the same THORChain-specific chain list regular market swaps already use to gate eligibility — rather than replacing `lpChainMap` outright or switching to the broader `nativeSwapChainIds`, which also carries MayaChain-only entries (e.g. `Chain.MayaChain`, `Chain.Cardano`) that aren't valid THORChain limit-swap destinations.
18
+
19
+ - [#1097](https://github.com/vultisig/vultisig-sdk/pull/1097) [`ffc75a6`](https://github.com/vultisig/vultisig-sdk/commit/ffc75a6e76af699a78b0fc3411ab052ce5000c91) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - fix(swap): exact bigint decimal conversion for the displayed swap output (`toAmountDecimal`) — the float64 `fromChainAmount(...).toFixed()` path silently drifted above 2^53 raw units (e.g. `999999999999999999999999` @18dp rendered as `1000000.000000000000000000`), so the amount the user confirmed could differ from the quoted one. Non-integer provider amount strings keep the legacy fallback instead of throwing mid-build.
20
+
3
21
  ## 2.24.1
4
22
 
5
23
  ### Patch Changes
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Exact base-units → human decimal-string conversion.
3
+ *
4
+ * `fromChainAmount` round-trips through float64 (`Number(amount) / 10**decimals`),
5
+ * which silently loses precision once the raw amount exceeds 2^53 (~0.009 tokens
6
+ * at 18 decimals) — `.toFixed(decimals)` then fabricates digits, so the displayed
7
+ * amount can differ from the quoted one (e.g. `999999999999999999999999` raw at
8
+ * 18dp renders as `1000000.000000000000000000`). This variant is pure bigint
9
+ * string arithmetic — no precision loss for any magnitude.
10
+ *
11
+ * Output format matches `fromChainAmount(x, d).toFixed(d)`: an unsigned decimal
12
+ * with exactly `decimals` fraction digits (no fraction part when `decimals` is 0),
13
+ * so it is a drop-in replacement for display fields like `toAmountDecimal`.
14
+ *
15
+ * Accepts the integer base-unit shapes quote APIs return: bigint, or a base-10
16
+ * integer string. Throws on anything else — a non-integer quote amount must be
17
+ * handled by the caller, never silently floated.
18
+ */
19
+ export declare const fromChainAmountExact: (amount: bigint | string, decimals: number) => string;
20
+ /**
21
+ * Display-oriented variant with a legacy fallback: exact conversion for the
22
+ * integer base-unit strings quote APIs are contracted to return, and the old
23
+ * float64 `.toFixed(decimals)` behaviour for anything else (some aggregators
24
+ * have been observed returning non-integer `dstAmount` strings — see
25
+ * SDK-CORRECTNESS-04; a display field must not throw mid-build over one).
26
+ */
27
+ export declare const fromChainAmountDisplay: (amount: bigint | string, decimals: number) => string;
28
+ //# sourceMappingURL=fromChainAmountExact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromChainAmountExact.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/amount/fromChainAmountExact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,GAAG,MAAM,EAAE,UAAU,MAAM,KAAG,MAkBhF,CAAA;AAID;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,GAAG,MAAM,EAAE,UAAU,MAAM,KAAG,MAMlF,CAAA"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Exact base-units → human decimal-string conversion.
3
+ *
4
+ * `fromChainAmount` round-trips through float64 (`Number(amount) / 10**decimals`),
5
+ * which silently loses precision once the raw amount exceeds 2^53 (~0.009 tokens
6
+ * at 18 decimals) — `.toFixed(decimals)` then fabricates digits, so the displayed
7
+ * amount can differ from the quoted one (e.g. `999999999999999999999999` raw at
8
+ * 18dp renders as `1000000.000000000000000000`). This variant is pure bigint
9
+ * string arithmetic — no precision loss for any magnitude.
10
+ *
11
+ * Output format matches `fromChainAmount(x, d).toFixed(d)`: an unsigned decimal
12
+ * with exactly `decimals` fraction digits (no fraction part when `decimals` is 0),
13
+ * so it is a drop-in replacement for display fields like `toAmountDecimal`.
14
+ *
15
+ * Accepts the integer base-unit shapes quote APIs return: bigint, or a base-10
16
+ * integer string. Throws on anything else — a non-integer quote amount must be
17
+ * handled by the caller, never silently floated.
18
+ */
19
+ export const fromChainAmountExact = (amount, decimals) => {
20
+ if (!Number.isInteger(decimals) || decimals < 0) {
21
+ throw new Error(`fromChainAmountExact: invalid decimals ${decimals}`);
22
+ }
23
+ const raw = typeof amount === 'bigint' ? amount : BigInt(amount.trim());
24
+ if (raw < 0n) {
25
+ throw new Error('fromChainAmountExact: negative amounts are not supported');
26
+ }
27
+ const s = raw.toString().padStart(decimals + 1, '0');
28
+ if (decimals === 0) {
29
+ return s;
30
+ }
31
+ return `${s.slice(0, -decimals)}.${s.slice(-decimals)}`;
32
+ };
33
+ const isIntegerString = (value) => /^\d+$/.test(value.trim());
34
+ /**
35
+ * Display-oriented variant with a legacy fallback: exact conversion for the
36
+ * integer base-unit strings quote APIs are contracted to return, and the old
37
+ * float64 `.toFixed(decimals)` behaviour for anything else (some aggregators
38
+ * have been observed returning non-integer `dstAmount` strings — see
39
+ * SDK-CORRECTNESS-04; a display field must not throw mid-build over one).
40
+ */
41
+ export const fromChainAmountDisplay = (amount, decimals) => {
42
+ if (typeof amount === 'bigint' || isIntegerString(amount)) {
43
+ return fromChainAmountExact(amount, decimals);
44
+ }
45
+ return (Number(amount) / Math.pow(10, decimals)).toFixed(decimals);
46
+ };
47
+ //# sourceMappingURL=fromChainAmountExact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromChainAmountExact.js","sourceRoot":"","sources":["../../../../../packages/core/chain/amount/fromChainAmountExact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAuB,EAAE,QAAgB,EAAU,EAAE;IACxF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,0CAA0C,QAAQ,EAAE,CAAC,CAAA;IACvE,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;IAEvE,IAAI,GAAG,GAAG,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IAEpD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAA;AACzD,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAuB,EAAE,QAAgB,EAAU,EAAE;IAC1F,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,OAAO,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC/C,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AACpE,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"toChainAmount.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/amount/toChainAmount.ts"],"names":[],"mappings":"AAEA,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAkB,IAAI,2BAA0B;gBAEpC,OAAO,EAAE,MAAM;CAG5B;AA+ED,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,GAAG,MAAM,EAAE,UAAU,MAAM,WAetE,CAAA"}
1
+ {"version":3,"file":"toChainAmount.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/amount/toChainAmount.ts"],"names":[],"mappings":"AAEA,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAkB,IAAI,2BAA0B;gBAEpC,OAAO,EAAE,MAAM;CAG5B;AAoGD,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,GAAG,MAAM,EAAE,UAAU,MAAM,WAatE,CAAA"}
@@ -75,6 +75,28 @@ const expandScientificNotationToDecimalString = (s) => {
75
75
  }
76
76
  return absResult;
77
77
  };
78
+ const formatNumberAmount = (amount) => {
79
+ const str = amount.toString();
80
+ return /[eE]/.test(str) ? expandScientificNotationToDecimalString(str) : str;
81
+ };
82
+ /**
83
+ * Truncate a plain decimal string to at most `decimals` fractional digits so
84
+ * parseUnits cannot round up. viem's parseUnits rounds half-up at decimals=0
85
+ * (e.g. "0.6" → 1n, "1.5" → 2n), while the signed amount must never exceed
86
+ * the stated human amount — truncation is the safe direction.
87
+ * Only called after scientific notation has already been expanded.
88
+ */
89
+ const truncateToDecimals = (s, decimals) => {
90
+ const dotIdx = s.indexOf('.');
91
+ if (dotIdx === -1)
92
+ return s;
93
+ if (decimals === 0)
94
+ return s.slice(0, dotIdx);
95
+ const fracPart = s.slice(dotIdx + 1);
96
+ if (fracPart.length <= decimals)
97
+ return s;
98
+ return `${s.slice(0, dotIdx + 1)}${fracPart.slice(0, decimals)}`;
99
+ };
78
100
  export const toChainAmount = (amount, decimals) => {
79
101
  if (typeof amount === 'string') {
80
102
  const trimmed = amount.trim();
@@ -83,12 +105,10 @@ export const toChainAmount = (amount, decimals) => {
83
105
  }
84
106
  if (/[eE]/.test(trimmed)) {
85
107
  const expanded = expandScientificNotationToDecimalString(trimmed);
86
- return parseUnits(expanded, decimals);
108
+ return parseUnits(truncateToDecimals(expanded, decimals), decimals);
87
109
  }
88
- return parseUnits(trimmed, decimals);
110
+ return parseUnits(truncateToDecimals(trimmed, decimals), decimals);
89
111
  }
90
- const str = amount.toString();
91
- const value = /[eE]/.test(str) ? amount.toFixed(decimals) : str;
92
- return parseUnits(value, decimals);
112
+ return parseUnits(truncateToDecimals(formatNumberAmount(amount), decimals), decimals);
93
113
  };
94
114
  //# sourceMappingURL=toChainAmount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toChainAmount.js","sourceRoot":"","sources":["../../../../../packages/core/chain/amount/toChainAmount.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toChainAmount.js","sourceRoot":"","sources":["../../../../../packages/core/chain/amount/toChainAmount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAEjC,iFAAiF;AACjF,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC5B,IAAI,GAAG,uBAAuB,CAAA;IAEhD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC;CACF;AAED,MAAM,kBAAkB,GAAG,mDAAmD,CAAA;AAE9E,iFAAiF;AACjF,MAAM,aAAa,GAAG,MAAO,CAAA;AAE7B,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAU,EAAE;IACnE,MAAM,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3C,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACf,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC5C,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAA;IAC7C,CAAC;IACD,IAAI,GAAG,GAAG,IAAI,CAAA;IACd,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;QACrC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;IACjB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,uCAAuC,GAAG,CAAC,CAAS,EAAU,EAAE;IACpE,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAC3C,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,qBAAqB,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAA;IAC5B,IAAI,QAAgB,CAAA;IACpB,IAAI,OAAe,CAAA;IACnB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACvB,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACf,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA;IAC3B,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;QACvC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAA;IAC/B,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,qBAAqB,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACzB,IAAI,MAAM,KAAK,EAAE,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACtD,MAAM,IAAI,qBAAqB,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,QAAQ,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;IAC5C,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,qBAAqB,CAAC,4CAA4C,CAAC,GAAG,CAAC,CAAA;IACnF,CAAC;IAED,IAAI,SAAiB,CAAA;IACrB,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,GAAG,IAAI,KAAK,CAAA;QACzB,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC3C,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,GAAG,CAAC,KAAK,CAAA;QAChB,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,CAAA;QACxB,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;QACnC,MAAM,GAAG,GAAG,SAAS,GAAG,OAAO,CAAA;QAC/B,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;QACjD,SAAS,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAA;IAC5E,CAAC;IAED,IAAI,OAAO,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;QAChC,OAAO,IAAI,SAAS,EAAE,CAAA;IACxB,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAU,EAAE;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;IAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,uCAAuC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAC9E,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG,CAAC,CAAS,EAAE,QAAgB,EAAU,EAAE;IACjE,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC7B,IAAI,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,CAAC,CAAA;IAC3B,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACpC,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,CAAC,CAAA;IACzC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAA;AAClE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAuB,EAAE,QAAgB,EAAE,EAAE;IACzE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;QAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,qBAAqB,CAAC,wBAAwB,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,uCAAuC,CAAC,OAAO,CAAC,CAAA;YACjE,OAAO,UAAU,CAAC,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAA;QACrE,CAAC;QACD,OAAO,UAAU,CAAC,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAA;IACpE,CAAC;IACD,OAAO,UAAU,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAA;AACvF,CAAC,CAAA"}
@@ -0,0 +1,96 @@
1
+ import { AddressLookupTableAccount, PublicKey, VersionedMessage } from '@solana/web3.js';
2
+ /**
3
+ * Programs a legitimate Jupiter swap is expected to invoke as a TOP-LEVEL
4
+ * instruction. Captured empirically (2026-07-09) by fetching real `/swap`
5
+ * responses from Jupiter's public API (`lite-api.jup.ag`) and decoding the
6
+ * returned `VersionedTransaction` across four scenarios:
7
+ * - a single-hop SOL -> USDC route
8
+ * - a 3-hop SOL -> BONK route (AlphaQ -> Hadron -> Raydium CLMM)
9
+ * - a Token-2022 output mint (SOL -> PYUSD)
10
+ * - a platform-fee-included swap (feeAccount + platformFeeBps set)
11
+ *
12
+ * Every one of them resolved to exactly this program set. `useSharedAccounts`
13
+ * (Jupiter's default) routes the actual AMM legs through the router via CPI,
14
+ * so the individual AMM programs (Raydium, Whirlpool, etc.) never surface as
15
+ * top-level instructions — only the router itself plus the
16
+ * wrapping/bookkeeping instructions (SOL wrap/unwrap, ATA create, compute
17
+ * budget) do. Token-2022 is allow-listed defensively even though it did not
18
+ * surface in any captured fixture (the wSOL leg always uses the legacy Token
19
+ * program): the SDK's own fee-ATA derivation
20
+ * (`packages/core/chain/swap/general/jupiter/api/jupiterFeeAta.ts`)
21
+ * explicitly supports Token-2022 mints, so a route with no wSOL leg could
22
+ * plausibly need it.
23
+ */
24
+ export declare const JUPITER_SWAP_ALLOWED_PROGRAM_IDS: ReadonlySet<string>;
25
+ /**
26
+ * Thrown when a Solana swap message contains a top-level instruction that
27
+ * targets a program outside {@link JUPITER_SWAP_ALLOWED_PROGRAM_IDS}.
28
+ */
29
+ export declare class UnsafeSolanaSwapInstructionError extends Error {
30
+ readonly instructionIndex: number;
31
+ readonly programId: string;
32
+ constructor(instructionIndex: number, programId: string);
33
+ }
34
+ /**
35
+ * Thrown when a fund-moving instruction (System/Token) in a swap message has
36
+ * a destination or authority that does not belong to the user.
37
+ *
38
+ * Audit finding SOL-01 residual: a program-only allow-list permits injected
39
+ * top-level `SystemProgram.Transfer { from: user, to: attacker }` or
40
+ * `Token.Approve { owner: user, delegate: attacker }` because those programs
41
+ * are allow-listed (needed for SOL wrap/unwrap). This error is thrown when the
42
+ * decoded instruction accounts don't match the user's controlled addresses.
43
+ */
44
+ export declare class UnsafeSolanaSwapFundMovementError extends Error {
45
+ readonly instructionIndex: number;
46
+ readonly reason: string;
47
+ constructor(instructionIndex: number, reason: string);
48
+ }
49
+ /**
50
+ * Fund-safety guard (audit finding SOL-01, vultisig/vultisig-sdk#1056): a
51
+ * compromised Jupiter proxy could inject an arbitrary instruction (e.g. a
52
+ * drain transfer) into the `VersionedTransaction` returned from `/swap`
53
+ * before it reaches MPC signing. Vultisig's signing UI cannot meaningfully
54
+ * render raw Solana instruction bytes for the user to review, so the
55
+ * transaction would be effectively blind-signed.
56
+ *
57
+ * Two-layer defense:
58
+ *
59
+ * 1. **Program allow-list**: every top-level instruction's `programIdIndex`
60
+ * must resolve to a program in {@link JUPITER_SWAP_ALLOWED_PROGRAM_IDS}.
61
+ * Throws {@link UnsafeSolanaSwapInstructionError} on any unrecognized program.
62
+ *
63
+ * 2. **Destination/authority validation for fund-moving programs**: a
64
+ * program-only check is insufficient because `SystemProgram`,
65
+ * `TOKEN_PROGRAM_ID`, and `TOKEN_2022_PROGRAM_ID` are allow-listed (they
66
+ * perform legitimate SOL wrap/unwrap) but also implement drain/seize
67
+ * primitives (`Transfer`, `Approve`, `SetAuthority`). For each instruction
68
+ * targeting those programs, the decoded accounts are validated:
69
+ * - `SystemProgram.Transfer`: destination must be the user's wSOL ATA; any
70
+ * other System discriminant (TransferWithSeed / CreateAccount*) rejected.
71
+ * - `Token.Transfer/TransferChecked`: rejected outright — a top-level token
72
+ * move is never part of a legitimate Jupiter shared-accounts swap (the
73
+ * router moves tokens via CPI), and validating authority==user is
74
+ * meaningless since the authority is definitionally the user for any drain
75
+ * of their own account. The distinguishing account is the destination.
76
+ * - `Token.CloseAccount`: destination must be the user wallet.
77
+ * - `Token.Approve/ApproveChecked/SetAuthority`: rejected outright.
78
+ * Throws {@link UnsafeSolanaSwapFundMovementError} on any violation.
79
+ *
80
+ * Does NOT — and cannot, via static inspection alone — see into CPI (a
81
+ * program invoked from inside another instruction); that's exactly what the
82
+ * allow-listed Jupiter router is trusted to CPI into on the user's behalf.
83
+ */
84
+ export declare const assertSafeSolanaSwapInstructions: (message: VersionedMessage, addressLookupTableAccounts: AddressLookupTableAccount[] | undefined, userWallet: PublicKey) => void;
85
+ /**
86
+ * Resolve every address-lookup-table referenced by a v0 message. Returns an
87
+ * empty array for legacy messages (which cannot reference LUTs).
88
+ */
89
+ export declare const resolveSolanaAddressLookupTables: (message: VersionedMessage) => Promise<AddressLookupTableAccount[]>;
90
+ /**
91
+ * Convenience wrapper: deserialize a base64-encoded `VersionedTransaction`,
92
+ * resolve any referenced LUTs, and assert its top-level instructions are
93
+ * all allow-listed and fund-movement-safe. See {@link assertSafeSolanaSwapInstructions}.
94
+ */
95
+ export declare const assertSafeSolanaSwapTransactionBase64: (txData: string, userWallet: PublicKey) => Promise<void>;
96
+ //# sourceMappingURL=assertSafeSolanaSwapInstructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertSafeSolanaSwapInstructions.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/solana/assertSafeSolanaSwapInstructions.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,yBAAyB,EAEzB,SAAS,EACT,gBAAgB,EAEjB,MAAM,iBAAiB,CAAA;AASxB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,gCAAgC,EAAE,WAAW,CAAC,MAAM,CAO/D,CAAA;AAoBF;;;GAGG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;aAEvC,gBAAgB,EAAE,MAAM;aACxB,SAAS,EAAE,MAAM;gBADjB,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM;CAOpC;AAED;;;;;;;;;GASG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;aAExC,gBAAgB,EAAE,MAAM;aACxB,MAAM,EAAE,MAAM;gBADd,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM;CAKjC;AAgHD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,gCAAgC,GAC3C,SAAS,gBAAgB,EACzB,4BAA4B,yBAAyB,EAAE,YAAK,EAC5D,YAAY,SAAS,KACpB,IAuBF,CAAA;AAyBD;;;GAGG;AACH,eAAO,MAAM,gCAAgC,GAC3C,SAAS,gBAAgB,KACxB,OAAO,CAAC,yBAAyB,EAAE,CAarC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,GAAU,QAAQ,MAAM,EAAE,YAAY,SAAS,KAAG,OAAO,CAAC,IAAI,CAI/G,CAAA"}
@@ -0,0 +1,260 @@
1
+ import { ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, NATIVE_MINT, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, } from '@solana/spl-token';
2
+ import { VersionedTransaction, } from '@solana/web3.js';
3
+ import { getSolanaClient } from './client.js';
4
+ /** Jupiter v6 aggregator router. Every Jupiter swap routes through this program. */
5
+ const JUPITER_V6_PROGRAM_ID = 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4';
6
+ const COMPUTE_BUDGET_PROGRAM_ID = 'ComputeBudget111111111111111111111111111111';
7
+ const SYSTEM_PROGRAM_ID = '11111111111111111111111111111111';
8
+ /**
9
+ * Programs a legitimate Jupiter swap is expected to invoke as a TOP-LEVEL
10
+ * instruction. Captured empirically (2026-07-09) by fetching real `/swap`
11
+ * responses from Jupiter's public API (`lite-api.jup.ag`) and decoding the
12
+ * returned `VersionedTransaction` across four scenarios:
13
+ * - a single-hop SOL -> USDC route
14
+ * - a 3-hop SOL -> BONK route (AlphaQ -> Hadron -> Raydium CLMM)
15
+ * - a Token-2022 output mint (SOL -> PYUSD)
16
+ * - a platform-fee-included swap (feeAccount + platformFeeBps set)
17
+ *
18
+ * Every one of them resolved to exactly this program set. `useSharedAccounts`
19
+ * (Jupiter's default) routes the actual AMM legs through the router via CPI,
20
+ * so the individual AMM programs (Raydium, Whirlpool, etc.) never surface as
21
+ * top-level instructions — only the router itself plus the
22
+ * wrapping/bookkeeping instructions (SOL wrap/unwrap, ATA create, compute
23
+ * budget) do. Token-2022 is allow-listed defensively even though it did not
24
+ * surface in any captured fixture (the wSOL leg always uses the legacy Token
25
+ * program): the SDK's own fee-ATA derivation
26
+ * (`packages/core/chain/swap/general/jupiter/api/jupiterFeeAta.ts`)
27
+ * explicitly supports Token-2022 mints, so a route with no wSOL leg could
28
+ * plausibly need it.
29
+ */
30
+ export const JUPITER_SWAP_ALLOWED_PROGRAM_IDS = new Set([
31
+ JUPITER_V6_PROGRAM_ID,
32
+ COMPUTE_BUDGET_PROGRAM_ID,
33
+ SYSTEM_PROGRAM_ID,
34
+ TOKEN_PROGRAM_ID.toBase58(),
35
+ TOKEN_2022_PROGRAM_ID.toBase58(),
36
+ ASSOCIATED_TOKEN_PROGRAM_ID.toBase58(),
37
+ ]);
38
+ /** Programs that can move funds — require destination/authority validation beyond a program-only check. */
39
+ const FUND_MOVING_PROGRAM_IDS = new Set([
40
+ SYSTEM_PROGRAM_ID,
41
+ TOKEN_PROGRAM_ID.toBase58(),
42
+ TOKEN_2022_PROGRAM_ID.toBase58(),
43
+ ]);
44
+ // SystemProgram instruction type discriminants (LE uint32 at data[0..4])
45
+ const SYSTEM_TRANSFER = 2;
46
+ // Token/Token-2022 instruction discriminants (uint8 at data[0])
47
+ const TOKEN_TRANSFER = 3;
48
+ const TOKEN_APPROVE = 4;
49
+ const TOKEN_SET_AUTHORITY = 6;
50
+ const TOKEN_CLOSE_ACCOUNT = 9;
51
+ const TOKEN_TRANSFER_CHECKED = 12;
52
+ const TOKEN_APPROVE_CHECKED = 13;
53
+ /**
54
+ * Thrown when a Solana swap message contains a top-level instruction that
55
+ * targets a program outside {@link JUPITER_SWAP_ALLOWED_PROGRAM_IDS}.
56
+ */
57
+ export class UnsafeSolanaSwapInstructionError extends Error {
58
+ instructionIndex;
59
+ programId;
60
+ constructor(instructionIndex, programId) {
61
+ super(`SOL_SWAP_UNEXPECTED_PROGRAM: instruction ${instructionIndex} targets unrecognized program ${programId}; refusing to sign`);
62
+ this.instructionIndex = instructionIndex;
63
+ this.programId = programId;
64
+ this.name = 'UnsafeSolanaSwapInstructionError';
65
+ }
66
+ }
67
+ /**
68
+ * Thrown when a fund-moving instruction (System/Token) in a swap message has
69
+ * a destination or authority that does not belong to the user.
70
+ *
71
+ * Audit finding SOL-01 residual: a program-only allow-list permits injected
72
+ * top-level `SystemProgram.Transfer { from: user, to: attacker }` or
73
+ * `Token.Approve { owner: user, delegate: attacker }` because those programs
74
+ * are allow-listed (needed for SOL wrap/unwrap). This error is thrown when the
75
+ * decoded instruction accounts don't match the user's controlled addresses.
76
+ */
77
+ export class UnsafeSolanaSwapFundMovementError extends Error {
78
+ instructionIndex;
79
+ reason;
80
+ constructor(instructionIndex, reason) {
81
+ super(`SOL_SWAP_UNSAFE_FUND_MOVEMENT: instruction ${instructionIndex} — ${reason}`);
82
+ this.instructionIndex = instructionIndex;
83
+ this.reason = reason;
84
+ this.name = 'UnsafeSolanaSwapFundMovementError';
85
+ }
86
+ }
87
+ const assertSystemInstruction = (ix, keys, userWallet, index) => {
88
+ if (ix.data.length < 4)
89
+ return;
90
+ const type = new DataView(ix.data.buffer, ix.data.byteOffset, 4).getUint32(0, /* littleEndian */ true);
91
+ // A legitimate top-level Jupiter swap only ever emits SystemProgram.Transfer
92
+ // (the SOL→wSOL wrap). Every OTHER System instruction that moves lamports —
93
+ // TransferWithSeed (11), CreateAccount (0), CreateAccountWithSeed (3) — is
94
+ // rejected outright rather than silently allowed: a program-only allow-list
95
+ // would let a spliced TransferWithSeed to an attacker survive into the signed
96
+ // bytes exactly like the Token.Transfer drain. Mirrors the reject-outright
97
+ // stance the token branch takes for non-wrap fund movers. Non-lamport-moving
98
+ // System instructions don't appear top-level in a swap, so a blanket reject of
99
+ // "not SYSTEM_TRANSFER" is the safe, tight floor (fail-closed on the unknown).
100
+ if (type !== SYSTEM_TRANSFER) {
101
+ throw new UnsafeSolanaSwapFundMovementError(index, `SystemProgram instruction (discriminant ${type}) is not a legitimate top-level Jupiter swap instruction — only SystemProgram.Transfer (SOL wrap) is expected`);
102
+ }
103
+ // Transfer accounts[1] = destination. The only legitimate SOL transfer in
104
+ // a Jupiter swap is wrapping: from: userWallet → to: userWallet's wSOL ATA.
105
+ const destIdx = ix.accountKeyIndexes[1];
106
+ if (destIdx === undefined) {
107
+ throw new UnsafeSolanaSwapFundMovementError(index, 'SystemProgram.Transfer: missing destination account index');
108
+ }
109
+ const dest = keys.get(destIdx);
110
+ if (!dest) {
111
+ throw new UnsafeSolanaSwapFundMovementError(index, `SystemProgram.Transfer: destination index ${destIdx} could not be resolved`);
112
+ }
113
+ const wSolAta = getAssociatedTokenAddressSync(NATIVE_MINT, userWallet);
114
+ if (!dest.equals(wSolAta)) {
115
+ throw new UnsafeSolanaSwapFundMovementError(index, `SystemProgram.Transfer destination ${dest.toBase58()} is not the expected wSOL ATA ${wSolAta.toBase58()} — possible drain injection`);
116
+ }
117
+ };
118
+ const assertTokenInstruction = (ix, keys, userWallet, index) => {
119
+ if (ix.data.length === 0)
120
+ return;
121
+ const type = ix.data[0];
122
+ // Reject instructions that can delegate or transfer authority — these are
123
+ // never present as top-level instructions in legitimate Jupiter shared-accounts swaps.
124
+ if (type === TOKEN_APPROVE || type === TOKEN_APPROVE_CHECKED) {
125
+ throw new UnsafeSolanaSwapFundMovementError(index, `Token.${type === TOKEN_APPROVE ? 'Approve' : 'ApproveChecked'} is not a legitimate top-level Jupiter swap instruction — possible authority delegation to attacker`);
126
+ }
127
+ if (type === TOKEN_SET_AUTHORITY) {
128
+ throw new UnsafeSolanaSwapFundMovementError(index, 'Token.SetAuthority is not a legitimate top-level Jupiter swap instruction — possible account seizure');
129
+ }
130
+ // Transfer (type=3) and TransferChecked (type=12): reject outright as
131
+ // top-level instructions. Jupiter shared-accounts routing performs token
132
+ // moves via CPI inside the router — a top-level Token.Transfer with
133
+ // authority==user and destination==attacker would pass an authority check
134
+ // and silently drain the user's tokens. Same rationale as Approve.
135
+ if (type === TOKEN_TRANSFER) {
136
+ throw new UnsafeSolanaSwapFundMovementError(index, 'Token.Transfer is not a legitimate top-level Jupiter swap instruction — possible token drain to attacker');
137
+ }
138
+ if (type === TOKEN_TRANSFER_CHECKED) {
139
+ throw new UnsafeSolanaSwapFundMovementError(index, 'Token.TransferChecked is not a legitimate top-level Jupiter swap instruction — possible token drain to attacker');
140
+ }
141
+ // CloseAccount (type=9): layout [account, destination, authority].
142
+ // accounts[1]=destination must be the user wallet so unwrapped SOL/rent
143
+ // returns to the user and cannot be swept to an attacker address.
144
+ if (type === TOKEN_CLOSE_ACCOUNT) {
145
+ const destIdx = ix.accountKeyIndexes[1];
146
+ if (destIdx === undefined)
147
+ throw new UnsafeSolanaSwapFundMovementError(index, 'Token.CloseAccount: missing destination account index');
148
+ const dest = keys.get(destIdx);
149
+ if (!dest || !dest.equals(userWallet)) {
150
+ throw new UnsafeSolanaSwapFundMovementError(index, `Token.CloseAccount destination ${dest?.toBase58() ?? '<unresolved>'} is not the user wallet ${userWallet.toBase58()} — possible SOL/rent drain`);
151
+ }
152
+ }
153
+ // SyncNative (17), InitializeAccount (1), and other Token instructions
154
+ // that do not move funds to an arbitrary destination: allowed.
155
+ };
156
+ /**
157
+ * Fund-safety guard (audit finding SOL-01, vultisig/vultisig-sdk#1056): a
158
+ * compromised Jupiter proxy could inject an arbitrary instruction (e.g. a
159
+ * drain transfer) into the `VersionedTransaction` returned from `/swap`
160
+ * before it reaches MPC signing. Vultisig's signing UI cannot meaningfully
161
+ * render raw Solana instruction bytes for the user to review, so the
162
+ * transaction would be effectively blind-signed.
163
+ *
164
+ * Two-layer defense:
165
+ *
166
+ * 1. **Program allow-list**: every top-level instruction's `programIdIndex`
167
+ * must resolve to a program in {@link JUPITER_SWAP_ALLOWED_PROGRAM_IDS}.
168
+ * Throws {@link UnsafeSolanaSwapInstructionError} on any unrecognized program.
169
+ *
170
+ * 2. **Destination/authority validation for fund-moving programs**: a
171
+ * program-only check is insufficient because `SystemProgram`,
172
+ * `TOKEN_PROGRAM_ID`, and `TOKEN_2022_PROGRAM_ID` are allow-listed (they
173
+ * perform legitimate SOL wrap/unwrap) but also implement drain/seize
174
+ * primitives (`Transfer`, `Approve`, `SetAuthority`). For each instruction
175
+ * targeting those programs, the decoded accounts are validated:
176
+ * - `SystemProgram.Transfer`: destination must be the user's wSOL ATA; any
177
+ * other System discriminant (TransferWithSeed / CreateAccount*) rejected.
178
+ * - `Token.Transfer/TransferChecked`: rejected outright — a top-level token
179
+ * move is never part of a legitimate Jupiter shared-accounts swap (the
180
+ * router moves tokens via CPI), and validating authority==user is
181
+ * meaningless since the authority is definitionally the user for any drain
182
+ * of their own account. The distinguishing account is the destination.
183
+ * - `Token.CloseAccount`: destination must be the user wallet.
184
+ * - `Token.Approve/ApproveChecked/SetAuthority`: rejected outright.
185
+ * Throws {@link UnsafeSolanaSwapFundMovementError} on any violation.
186
+ *
187
+ * Does NOT — and cannot, via static inspection alone — see into CPI (a
188
+ * program invoked from inside another instruction); that's exactly what the
189
+ * allow-listed Jupiter router is trusted to CPI into on the user's behalf.
190
+ */
191
+ export const assertSafeSolanaSwapInstructions = (message, addressLookupTableAccounts = [], userWallet) => {
192
+ const accountKeys = message.version === 'legacy' ? message.getAccountKeys() : message.getAccountKeys({ addressLookupTableAccounts });
193
+ message.compiledInstructions.forEach((instruction, index) => {
194
+ const programId = accountKeys.get(instruction.programIdIndex);
195
+ if (!programId) {
196
+ throw new UnsafeSolanaSwapInstructionError(index, `<unresolved account index ${instruction.programIdIndex}>`);
197
+ }
198
+ const programIdBase58 = programId.toBase58();
199
+ if (!JUPITER_SWAP_ALLOWED_PROGRAM_IDS.has(programIdBase58)) {
200
+ throw new UnsafeSolanaSwapInstructionError(index, programIdBase58);
201
+ }
202
+ // Layer 2: for fund-moving programs, validate destination/authority
203
+ if (FUND_MOVING_PROGRAM_IDS.has(programIdBase58)) {
204
+ if (programIdBase58 === SYSTEM_PROGRAM_ID) {
205
+ assertSystemInstruction(instruction, accountKeys, userWallet, index);
206
+ }
207
+ else {
208
+ assertTokenInstruction(instruction, accountKeys, userWallet, index);
209
+ }
210
+ }
211
+ });
212
+ };
213
+ /** Maximum attempts for a LUT fetch before giving up on that table. */
214
+ const MAX_LUT_FETCH_ATTEMPTS = 3;
215
+ const fetchLutWithRetry = async (client, accountKey) => {
216
+ const errors = [];
217
+ for (let attempt = 0; attempt < MAX_LUT_FETCH_ATTEMPTS; attempt++) {
218
+ try {
219
+ const result = await client.getAddressLookupTable(accountKey);
220
+ return result.value ?? null;
221
+ }
222
+ catch (err) {
223
+ errors.push(err);
224
+ if (attempt < MAX_LUT_FETCH_ATTEMPTS - 1) {
225
+ await new Promise(resolve => setTimeout(resolve, 200 * 2 ** attempt));
226
+ }
227
+ }
228
+ }
229
+ console.warn('[assertSafeSolanaSwapInstructions] LUT fetch failed after retries:', errors);
230
+ return null;
231
+ };
232
+ /**
233
+ * Resolve every address-lookup-table referenced by a v0 message. Returns an
234
+ * empty array for legacy messages (which cannot reference LUTs).
235
+ */
236
+ export const resolveSolanaAddressLookupTables = async (message) => {
237
+ if (message.version !== 0) {
238
+ return [];
239
+ }
240
+ const client = getSolanaClient();
241
+ const lutAccounts = [];
242
+ for (const lut of message.addressTableLookups) {
243
+ const lutAccount = await fetchLutWithRetry(client, lut.accountKey);
244
+ if (lutAccount) {
245
+ lutAccounts.push(lutAccount);
246
+ }
247
+ }
248
+ return lutAccounts;
249
+ };
250
+ /**
251
+ * Convenience wrapper: deserialize a base64-encoded `VersionedTransaction`,
252
+ * resolve any referenced LUTs, and assert its top-level instructions are
253
+ * all allow-listed and fund-movement-safe. See {@link assertSafeSolanaSwapInstructions}.
254
+ */
255
+ export const assertSafeSolanaSwapTransactionBase64 = async (txData, userWallet) => {
256
+ const versionedTx = VersionedTransaction.deserialize(Buffer.from(txData, 'base64'));
257
+ const lutAccounts = await resolveSolanaAddressLookupTables(versionedTx.message);
258
+ assertSafeSolanaSwapInstructions(versionedTx.message, lutAccounts, userWallet);
259
+ };
260
+ //# sourceMappingURL=assertSafeSolanaSwapInstructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertSafeSolanaSwapInstructions.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/solana/assertSafeSolanaSwapInstructions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getJupiterSwapQuote.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/swap/general/jupiter/api/getJupiterSwapQuote.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAA;AACrF,OAAO,EAEL,KAAK,sBAAsB,EAG5B,MAAM,kDAAkD,CAAA;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oEAAoE,CAAA;AAE5G,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAUzE,KAAK,KAAK,GAAG,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,uBAAuB,CAAC,CAAC,GAAG;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,sBAAsB,CAAA;IACtC,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AA2CD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAAU,iEAOvC,KAAK,KAAG,OAAO,CAAC,gBAAgB,CA8FlC,CAAA"}
1
+ {"version":3,"file":"getJupiterSwapQuote.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/swap/general/jupiter/api/getJupiterSwapQuote.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAA;AACrF,OAAO,EAEL,KAAK,sBAAsB,EAG5B,MAAM,kDAAkD,CAAA;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oEAAoE,CAAA;AAE5G,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAUzE,KAAK,KAAK,GAAG,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,uBAAuB,CAAC,CAAC,GAAG;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,sBAAsB,CAAA;IACtC,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AA2CD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAAU,iEAOvC,KAAK,KAAG,OAAO,CAAC,gBAAgB,CAsGlC,CAAA"}
@@ -1,4 +1,6 @@
1
+ import { PublicKey } from '@solana/web3.js';
1
2
  import { Chain } from '@vultisig/core-chain/Chain';
3
+ import { assertSafeSolanaSwapTransactionBase64 } from '@vultisig/core-chain/chains/solana/assertSafeSolanaSwapInstructions';
2
4
  import { solanaConfig } from '@vultisig/core-chain/chains/solana/solanaConfig';
3
5
  import { getJupiterConfig, jupiterFeeOwnerAddress, normalizeJupiterBaseUrl, } from '@vultisig/core-chain/swap/general/jupiter/config';
4
6
  import { assertJupiterPriceImpactWithinCeiling } from '@vultisig/core-chain/swap/general/priceImpactGuard';
@@ -86,6 +88,12 @@ export const getJupiterSwapQuote = async ({ from, to, amount, affiliateBps = 0,
86
88
  if (!swapResponse.swapTransaction) {
87
89
  throw new Error('Jupiter swap response did not include a serialized transaction.');
88
90
  }
91
+ // Fund-safety guard (audit finding SOL-01): the proxy-supplied transaction
92
+ // is validated BEFORE any local mutation (fee-ATA prepend), and regardless
93
+ // of whether a fee is charged on this swap — an unguarded no-fee response
94
+ // was previously forwarded to signing verbatim.
95
+ const userPubkey = new PublicKey(from.address);
96
+ await assertSafeSolanaSwapTransactionBase64(swapResponse.swapTransaction, userPubkey);
89
97
  const data = feeAccountInfo
90
98
  ? await prependJupiterFeeAta({
91
99
  txData: swapResponse.swapTransaction,
@@ -93,6 +101,7 @@ export const getJupiterSwapQuote = async ({ from, to, amount, affiliateBps = 0,
93
101
  mintPubkey: feeAccountInfo.mintPubkey,
94
102
  ownerPubkey: feeAccountInfo.ownerPubkey,
95
103
  tokenProgramId: feeAccountInfo.tokenProgramId,
104
+ userWallet: userPubkey,
96
105
  })
97
106
  : swapResponse.swapTransaction;
98
107
  // Network fee is an upper-bound estimate: Solana's per-signature base fee plus
@@ -1 +1 @@
1
- {"version":3,"file":"getJupiterSwapQuote.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/swap/general/jupiter/api/getJupiterSwapQuote.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getJupiterSwapQuote.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/swap/general/jupiter/api/getJupiterSwapQuote.ts"],"names":[],"mappings":"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"}
@@ -38,11 +38,12 @@ export declare const deriveJupiterFeeAccount: ({ outputMint, feeOwner, }: {
38
38
  * keysign path refreshes the blockhash before broadcast (same as every other
39
39
  * Solana general-swap route), so we do not refresh it here.
40
40
  */
41
- export declare const prependJupiterFeeAta: ({ txData, feeAccount, mintPubkey, ownerPubkey, tokenProgramId, }: {
41
+ export declare const prependJupiterFeeAta: ({ txData, feeAccount, mintPubkey, ownerPubkey, tokenProgramId, userWallet, }: {
42
42
  txData: string;
43
43
  feeAccount: string;
44
44
  mintPubkey: PublicKey;
45
45
  ownerPubkey: PublicKey;
46
46
  tokenProgramId: PublicKey;
47
+ userWallet: PublicKey;
47
48
  }) => Promise<string>;
48
49
  //# sourceMappingURL=jupiterFeeAta.d.ts.map