@vultisig/core-chain 2.24.2 → 2.25.0
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/CHANGELOG.md +17 -0
- package/dist/amount/toChainAmount.d.ts.map +1 -1
- package/dist/amount/toChainAmount.js +5 -3
- package/dist/amount/toChainAmount.js.map +1 -1
- package/dist/chains/ripple/account/lines.d.ts +13 -0
- package/dist/chains/ripple/account/lines.d.ts.map +1 -0
- package/dist/chains/ripple/account/lines.js +28 -0
- package/dist/chains/ripple/account/lines.js.map +1 -0
- package/dist/chains/ripple/issuedCurrency.d.ts +17 -3
- package/dist/chains/ripple/issuedCurrency.d.ts.map +1 -1
- package/dist/chains/ripple/issuedCurrency.js +30 -3
- package/dist/chains/ripple/issuedCurrency.js.map +1 -1
- package/dist/chains/solana/assertSafeSolanaSwapInstructions.d.ts +96 -0
- package/dist/chains/solana/assertSafeSolanaSwapInstructions.d.ts.map +1 -0
- package/dist/chains/solana/assertSafeSolanaSwapInstructions.js +260 -0
- package/dist/chains/solana/assertSafeSolanaSwapInstructions.js.map +1 -0
- package/dist/coin/balance/resolvers/ripple.d.ts.map +1 -1
- package/dist/coin/balance/resolvers/ripple.js +40 -3
- package/dist/coin/balance/resolvers/ripple.js.map +1 -1
- package/dist/coin/find/CoinFinderChainKind.d.ts +1 -1
- package/dist/coin/find/CoinFinderChainKind.d.ts.map +1 -1
- package/dist/coin/find/CoinFinderChainKind.js +1 -1
- package/dist/coin/find/CoinFinderChainKind.js.map +1 -1
- package/dist/coin/find/index.d.ts.map +1 -1
- package/dist/coin/find/index.js +2 -0
- package/dist/coin/find/index.js.map +1 -1
- package/dist/coin/find/resolvers/ripple.d.ts +12 -0
- package/dist/coin/find/resolvers/ripple.d.ts.map +1 -0
- package/dist/coin/find/resolvers/ripple.js +50 -0
- package/dist/coin/find/resolvers/ripple.js.map +1 -0
- package/dist/coin/knownTokens/index.d.ts.map +1 -1
- package/dist/coin/knownTokens/index.js +2 -0
- package/dist/coin/knownTokens/index.js.map +1 -1
- package/dist/swap/general/jupiter/api/getJupiterSwapQuote.d.ts.map +1 -1
- package/dist/swap/general/jupiter/api/getJupiterSwapQuote.js +9 -0
- package/dist/swap/general/jupiter/api/getJupiterSwapQuote.js.map +1 -1
- package/dist/swap/general/jupiter/api/jupiterFeeAta.d.ts +2 -1
- package/dist/swap/general/jupiter/api/jupiterFeeAta.d.ts.map +1 -1
- package/dist/swap/general/jupiter/api/jupiterFeeAta.js +7 -35
- package/dist/swap/general/jupiter/api/jupiterFeeAta.js.map +1 -1
- package/fixtures/jupiter-swap-transactions.json +30 -0
- package/package.json +17 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @vultisig/core-chain
|
|
2
2
|
|
|
3
|
+
## 2.25.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1169](https://github.com/vultisig/vultisig-sdk/pull/1169) [`1ef64a3`](https://github.com/vultisig/vultisig-sdk/commit/1ef64a39f856d9f1d412df8f5e69c66f7130d8c7) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Surface XRP issued-currency (trust-line) token balances.
|
|
8
|
+
|
|
9
|
+
- `getRippleAccountLines` reads an account's trust lines, following `account_lines` pagination so a large set is not truncated.
|
|
10
|
+
- `getRippleCoinBalance` now dispatches on the coin id: native XRP still returns the reserve-adjusted spendable balance, while an issued-currency coin returns that trust line's balance. Previously the resolver ignored the id and returned the XRP balance for _every_ Ripple coin, so a token row displayed the account's XRP balance.
|
|
11
|
+
- `findRippleCoins` discovers held trust lines for the coin finder, so XRPL tokens appear in the asset list. Lines with a negative balance (the account is the issuer and owes the counterparty) and zero-balance lines are excluded.
|
|
12
|
+
- `rippleKnownIssuedTokens` (RLUSD) is now wired into `knownTokens`, so it is selectable before a trust line exists.
|
|
13
|
+
|
|
14
|
+
## 2.24.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- [#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.
|
|
19
|
+
|
|
3
20
|
## 2.24.2
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -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;
|
|
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,10 @@ 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
|
+
};
|
|
78
82
|
/**
|
|
79
83
|
* Truncate a plain decimal string to at most `decimals` fractional digits so
|
|
80
84
|
* parseUnits cannot round up. viem's parseUnits rounds half-up at decimals=0
|
|
@@ -105,8 +109,6 @@ export const toChainAmount = (amount, decimals) => {
|
|
|
105
109
|
}
|
|
106
110
|
return parseUnits(truncateToDecimals(trimmed, decimals), decimals);
|
|
107
111
|
}
|
|
108
|
-
|
|
109
|
-
const value = /[eE]/.test(str) ? amount.toFixed(decimals) : str;
|
|
110
|
-
return parseUnits(truncateToDecimals(value, decimals), decimals);
|
|
112
|
+
return parseUnits(truncateToDecimals(formatNumberAmount(amount), decimals), decimals);
|
|
111
113
|
};
|
|
112
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,13 @@
|
|
|
1
|
+
import { AccountLinesTrustline } from 'xrpl';
|
|
2
|
+
/**
|
|
3
|
+
* Every trust line held by `address`, following `account_lines` pagination to
|
|
4
|
+
* completion. The XRP Ledger returns trust lines in pages, so a single request
|
|
5
|
+
* would silently truncate the set of an account with many lines and hide token
|
|
6
|
+
* balances rather than fail.
|
|
7
|
+
*
|
|
8
|
+
* Balances are signed from `address`'s perspective: a negative balance means
|
|
9
|
+
* `address` is the issuer and owes the counterparty, not that it holds the token.
|
|
10
|
+
* @see https://xrpl.org/docs/references/http-websocket-apis/public-api-methods/account-methods/account_lines
|
|
11
|
+
*/
|
|
12
|
+
export declare const getRippleAccountLines: (address: string) => Promise<AccountLinesTrustline[]>;
|
|
13
|
+
//# sourceMappingURL=lines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/ripple/account/lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAA;AAI5C;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,qBAAqB,EAAE,CAmB5F,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getRippleClient } from '../client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Every trust line held by `address`, following `account_lines` pagination to
|
|
4
|
+
* completion. The XRP Ledger returns trust lines in pages, so a single request
|
|
5
|
+
* would silently truncate the set of an account with many lines and hide token
|
|
6
|
+
* balances rather than fail.
|
|
7
|
+
*
|
|
8
|
+
* Balances are signed from `address`'s perspective: a negative balance means
|
|
9
|
+
* `address` is the issuer and owes the counterparty, not that it holds the token.
|
|
10
|
+
* @see https://xrpl.org/docs/references/http-websocket-apis/public-api-methods/account-methods/account_lines
|
|
11
|
+
*/
|
|
12
|
+
export const getRippleAccountLines = async (address) => {
|
|
13
|
+
const client = await getRippleClient();
|
|
14
|
+
const lines = [];
|
|
15
|
+
let marker = undefined;
|
|
16
|
+
do {
|
|
17
|
+
const { result } = await client.request({
|
|
18
|
+
command: 'account_lines',
|
|
19
|
+
account: address,
|
|
20
|
+
ledger_index: 'current',
|
|
21
|
+
...(marker === undefined ? {} : { marker }),
|
|
22
|
+
});
|
|
23
|
+
lines.push(...result.lines);
|
|
24
|
+
marker = result.marker;
|
|
25
|
+
} while (marker !== undefined);
|
|
26
|
+
return lines;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/ripple/account/lines.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EAAE,OAAe,EAAoC,EAAE;IAC/F,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;IAEtC,MAAM,KAAK,GAA4B,EAAE,CAAA;IACzC,IAAI,MAAM,GAAY,SAAS,CAAA;IAE/B,GAAG,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;YACtC,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,OAAO;YAChB,YAAY,EAAE,SAAS;YACvB,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;SAC5C,CAAC,CAAA;QAEF,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IACxB,CAAC,QAAQ,MAAM,KAAK,SAAS,EAAC;IAE9B,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|
|
@@ -47,9 +47,23 @@ export declare const formatIssuedCurrencyValue: (amount: bigint, decimals: numbe
|
|
|
47
47
|
*/
|
|
48
48
|
export declare const rippleIssuedCurrencyDecimals = 15;
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
51
|
-
* into
|
|
52
|
-
*
|
|
50
|
+
* Parses an XRPL issued-currency value string (as returned by `account_lines`)
|
|
51
|
+
* into a base-unit bigint at {@link rippleIssuedCurrencyDecimals}. The inverse of
|
|
52
|
+
* {@link formatIssuedCurrencyValue}.
|
|
53
|
+
*
|
|
54
|
+
* The ledger may return scientific notation (e.g. `1e-8`) as well as plain
|
|
55
|
+
* decimals, and values are signed — a negative balance means the account is the
|
|
56
|
+
* issuer of the line rather than a holder of it.
|
|
57
|
+
*
|
|
58
|
+
* Fractional digits beyond our modelled precision are truncated, never rounded
|
|
59
|
+
* up, so a dust balance can never be inflated into a larger holding.
|
|
60
|
+
*/
|
|
61
|
+
export declare const parseIssuedCurrencyValue: (value: string) => bigint;
|
|
62
|
+
/**
|
|
63
|
+
* Curated XRPL issued tokens, surfaced both in the "open trust line" flow and —
|
|
64
|
+
* via `knownTokens` — in the asset list. Trust lines the account already holds are
|
|
65
|
+
* discovered from the ledger by the Ripple coin finder; this list is what a user
|
|
66
|
+
* can pick before any trust line exists.
|
|
53
67
|
*/
|
|
54
68
|
export declare const rippleKnownIssuedTokens: KnownCoin[];
|
|
55
69
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issuedCurrency.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ripple/issuedCurrency.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,UAAU,CAAA;AAqB9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,MAYrD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,MAAM,KAAG,OAEyB,CAAA;AAIpF,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,sBAAsB,oBAAoB,KAAG,MACZ,CAAA;AAE/D,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,KAAG,oBAU/C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,KAAG,MAU5E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,KAAK,CAAA;AAE9C
|
|
1
|
+
{"version":3,"file":"issuedCurrency.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ripple/issuedCurrency.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,UAAU,CAAA;AAqB9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,MAYrD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,MAAM,KAAG,OAEyB,CAAA;AAIpF,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,sBAAsB,oBAAoB,KAAG,MACZ,CAAA;AAE/D,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,KAAG,oBAU/C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,KAAG,MAU5E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,KAAK,CAAA;AAE9C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,MAAM,KAAG,MAiBxD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,EAY9C,CAAA"}
|
|
@@ -84,9 +84,36 @@ export const formatIssuedCurrencyValue = (amount, decimals) => {
|
|
|
84
84
|
*/
|
|
85
85
|
export const rippleIssuedCurrencyDecimals = 15;
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
* into
|
|
89
|
-
*
|
|
87
|
+
* Parses an XRPL issued-currency value string (as returned by `account_lines`)
|
|
88
|
+
* into a base-unit bigint at {@link rippleIssuedCurrencyDecimals}. The inverse of
|
|
89
|
+
* {@link formatIssuedCurrencyValue}.
|
|
90
|
+
*
|
|
91
|
+
* The ledger may return scientific notation (e.g. `1e-8`) as well as plain
|
|
92
|
+
* decimals, and values are signed — a negative balance means the account is the
|
|
93
|
+
* issuer of the line rather than a holder of it.
|
|
94
|
+
*
|
|
95
|
+
* Fractional digits beyond our modelled precision are truncated, never rounded
|
|
96
|
+
* up, so a dust balance can never be inflated into a larger holding.
|
|
97
|
+
*/
|
|
98
|
+
export const parseIssuedCurrencyValue = (value) => {
|
|
99
|
+
const match = /^([+-]?)(\d+)(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/.exec(value.trim());
|
|
100
|
+
if (!match) {
|
|
101
|
+
throw new Error(`Invalid XRPL issued-currency value: "${value}"`);
|
|
102
|
+
}
|
|
103
|
+
const [, sign, intPart, fracPart = '', exponent = '0'] = match;
|
|
104
|
+
// The literal is `digits * 10^(exponent - fracPart.length)`, so scaling it to
|
|
105
|
+
// base units shifts by that plus our modelled decimals. Shifting the digit
|
|
106
|
+
// string rather than round-tripping through a float keeps full precision.
|
|
107
|
+
const shift = Number(exponent) - fracPart.length + rippleIssuedCurrencyDecimals;
|
|
108
|
+
const digits = BigInt(`${intPart}${fracPart}`);
|
|
109
|
+
const magnitude = shift >= 0 ? digits * 10n ** BigInt(shift) : digits / 10n ** BigInt(-shift);
|
|
110
|
+
return sign === '-' ? -magnitude : magnitude;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Curated XRPL issued tokens, surfaced both in the "open trust line" flow and —
|
|
114
|
+
* via `knownTokens` — in the asset list. Trust lines the account already holds are
|
|
115
|
+
* discovered from the ledger by the Ripple coin finder; this list is what a user
|
|
116
|
+
* can pick before any trust line exists.
|
|
90
117
|
*/
|
|
91
118
|
export const rippleKnownIssuedTokens = [
|
|
92
119
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issuedCurrency.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ripple/issuedCurrency.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"issuedCurrency.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ripple/issuedCurrency.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/balance/resolvers/ripple.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/balance/resolvers/ripple.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AA2EjD,eAAO,MAAM,oBAAoB,EAAE,mBAM3B,CAAA"}
|