@vultisig/core-chain 5.2.0 → 5.4.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.
Files changed (122) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/chains/solana/spl/verification.d.ts +38 -0
  3. package/dist/chains/solana/spl/verification.d.ts.map +1 -0
  4. package/dist/chains/solana/spl/verification.js +45 -0
  5. package/dist/chains/solana/spl/verification.js.map +1 -0
  6. package/dist/chains/solana/spl/verifiedRegistry.d.ts +34 -0
  7. package/dist/chains/solana/spl/verifiedRegistry.d.ts.map +1 -0
  8. package/dist/chains/solana/spl/verifiedRegistry.js +65 -0
  9. package/dist/chains/solana/spl/verifiedRegistry.js.map +1 -0
  10. package/dist/chains/ton/jetton/symbol.d.ts +3 -5
  11. package/dist/chains/ton/jetton/symbol.d.ts.map +1 -1
  12. package/dist/chains/ton/jetton/symbol.js +5 -58
  13. package/dist/chains/ton/jetton/symbol.js.map +1 -1
  14. package/dist/chains/ton/jetton/verification.d.ts +1 -1
  15. package/dist/chains/ton/jetton/verification.d.ts.map +1 -1
  16. package/dist/chains/ton/jetton/verification.js +3 -3
  17. package/dist/chains/ton/jetton/verification.js.map +1 -1
  18. package/dist/chains/ton/jetton/verifiedRegistry.d.ts +1 -1
  19. package/dist/chains/ton/jetton/verifiedRegistry.d.ts.map +1 -1
  20. package/dist/chains/ton/jetton/verifiedRegistry.js +3 -3
  21. package/dist/chains/ton/jetton/verifiedRegistry.js.map +1 -1
  22. package/dist/coin/balance/resolvers/tron.d.ts.map +1 -1
  23. package/dist/coin/balance/resolvers/tron.js +22 -34
  24. package/dist/coin/balance/resolvers/tron.js.map +1 -1
  25. package/dist/coin/coingecko/coingeckoToken.d.ts +11 -0
  26. package/dist/coin/coingecko/coingeckoToken.d.ts.map +1 -1
  27. package/dist/coin/coingecko/getCoingeckoId.d.ts +10 -0
  28. package/dist/coin/coingecko/getCoingeckoId.d.ts.map +1 -1
  29. package/dist/coin/coingecko/getCoingeckoId.js +30 -1
  30. package/dist/coin/coingecko/getCoingeckoId.js.map +1 -1
  31. package/dist/coin/find/resolvers/solana/index.d.ts +22 -1
  32. package/dist/coin/find/resolvers/solana/index.d.ts.map +1 -1
  33. package/dist/coin/find/resolvers/solana/index.js +79 -11
  34. package/dist/coin/find/resolvers/solana/index.js.map +1 -1
  35. package/dist/coin/jupiter/api.d.ts +18 -0
  36. package/dist/coin/jupiter/api.d.ts.map +1 -0
  37. package/dist/coin/jupiter/api.js +52 -0
  38. package/dist/coin/jupiter/api.js.map +1 -0
  39. package/dist/coin/jupiter/token.d.ts +4 -0
  40. package/dist/coin/jupiter/token.d.ts.map +1 -1
  41. package/dist/coin/jupiter/token.js.map +1 -1
  42. package/dist/coin/token/metadata/resolvers/solana.d.ts +3 -1
  43. package/dist/coin/token/metadata/resolvers/solana.d.ts.map +1 -1
  44. package/dist/coin/token/metadata/resolvers/solana.js +10 -6
  45. package/dist/coin/token/metadata/resolvers/solana.js.map +1 -1
  46. package/dist/coin/tokenSymbol.d.ts +10 -0
  47. package/dist/coin/tokenSymbol.d.ts.map +1 -0
  48. package/dist/coin/tokenSymbol.js +62 -0
  49. package/dist/coin/tokenSymbol.js.map +1 -0
  50. package/dist/security/blockaid/evmChains.d.ts +1 -0
  51. package/dist/security/blockaid/evmChains.d.ts.map +1 -1
  52. package/dist/security/blockaid/evmChains.js +3 -2
  53. package/dist/security/blockaid/evmChains.js.map +1 -1
  54. package/dist/security/blockaid/simulationChains.d.ts +1 -1
  55. package/dist/security/blockaid/simulationChains.d.ts.map +1 -1
  56. package/dist/security/blockaid/tx/simulation/api/core.d.ts +17 -0
  57. package/dist/security/blockaid/tx/simulation/api/core.d.ts.map +1 -1
  58. package/dist/security/blockaid/tx/simulation/api/core.js +58 -41
  59. package/dist/security/blockaid/tx/simulation/api/core.js.map +1 -1
  60. package/dist/security/blockaid/validationChains.d.ts +1 -1
  61. package/dist/security/blockaid/validationChains.d.ts.map +1 -1
  62. package/dist/swap/general/GeneralSwapQuote.d.ts +13 -0
  63. package/dist/swap/general/GeneralSwapQuote.d.ts.map +1 -1
  64. package/dist/swap/general/cowswap/api/getCowSwapQuote.d.ts.map +1 -1
  65. package/dist/swap/general/cowswap/api/getCowSwapQuote.js +5 -0
  66. package/dist/swap/general/cowswap/api/getCowSwapQuote.js.map +1 -1
  67. package/dist/swap/general/jupiter/api/getJupiterSwapQuote.d.ts.map +1 -1
  68. package/dist/swap/general/jupiter/api/getJupiterSwapQuote.js +4 -0
  69. package/dist/swap/general/jupiter/api/getJupiterSwapQuote.js.map +1 -1
  70. package/dist/swap/general/kyber/api/tx.d.ts.map +1 -1
  71. package/dist/swap/general/kyber/api/tx.js +9 -1
  72. package/dist/swap/general/kyber/api/tx.js.map +1 -1
  73. package/dist/swap/general/lifi/api/getLifiSwapQuote.d.ts.map +1 -1
  74. package/dist/swap/general/lifi/api/getLifiSwapQuote.js +2 -0
  75. package/dist/swap/general/lifi/api/getLifiSwapQuote.js.map +1 -1
  76. package/dist/swap/general/oneInch/api/getOneInchSwapQuote.d.ts.map +1 -1
  77. package/dist/swap/general/oneInch/api/getOneInchSwapQuote.js +5 -0
  78. package/dist/swap/general/oneInch/api/getOneInchSwapQuote.js.map +1 -1
  79. package/dist/swap/general/ruji/api/getRujiTradeSwapQuote.d.ts.map +1 -1
  80. package/dist/swap/general/ruji/api/getRujiTradeSwapQuote.js +1 -0
  81. package/dist/swap/general/ruji/api/getRujiTradeSwapQuote.js.map +1 -1
  82. package/dist/swap/general/swapkit/SwapKitEnabledChains.d.ts +3 -3
  83. package/dist/swap/general/swapkit/SwapKitEnabledChains.js +3 -3
  84. package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
  85. package/dist/swap/general/swapkit/api/getSwapKitQuote.js +41 -14
  86. package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
  87. package/dist/swap/native/NativeSwapQuote.d.ts +9 -1
  88. package/dist/swap/native/NativeSwapQuote.d.ts.map +1 -1
  89. package/dist/swap/native/api/affiliate.d.ts +6 -1
  90. package/dist/swap/native/api/affiliate.d.ts.map +1 -1
  91. package/dist/swap/native/api/affiliate.js +17 -6
  92. package/dist/swap/native/api/affiliate.js.map +1 -1
  93. package/dist/swap/native/api/getNativeSwapQuote.d.ts.map +1 -1
  94. package/dist/swap/native/api/getNativeSwapQuote.js +9 -10
  95. package/dist/swap/native/api/getNativeSwapQuote.js.map +1 -1
  96. package/dist/swap/quote/SwapQuote.d.ts +13 -0
  97. package/dist/swap/quote/SwapQuote.d.ts.map +1 -1
  98. package/dist/tx/fee/evm/clampEvmPriorityFee.d.ts +10 -4
  99. package/dist/tx/fee/evm/clampEvmPriorityFee.d.ts.map +1 -1
  100. package/dist/tx/fee/evm/clampEvmPriorityFee.js +35 -14
  101. package/dist/tx/fee/evm/clampEvmPriorityFee.js.map +1 -1
  102. package/dist/tx/fee/evm/evmGasLimit.d.ts +29 -0
  103. package/dist/tx/fee/evm/evmGasLimit.d.ts.map +1 -1
  104. package/dist/tx/fee/evm/evmGasLimit.js +47 -17
  105. package/dist/tx/fee/evm/evmGasLimit.js.map +1 -1
  106. package/dist/tx/fee/evm/gasPrice.d.ts +4 -0
  107. package/dist/tx/fee/evm/gasPrice.d.ts.map +1 -0
  108. package/dist/tx/fee/evm/gasPrice.js +4 -0
  109. package/dist/tx/fee/evm/gasPrice.js.map +1 -0
  110. package/dist/tx/fee/evm/maxPriorityFeePerGas.d.ts +8 -0
  111. package/dist/tx/fee/evm/maxPriorityFeePerGas.d.ts.map +1 -1
  112. package/dist/tx/fee/evm/maxPriorityFeePerGas.js +30 -1
  113. package/dist/tx/fee/evm/maxPriorityFeePerGas.js.map +1 -1
  114. package/dist/utils/isValidRecipient.d.ts +13 -0
  115. package/dist/utils/isValidRecipient.d.ts.map +1 -0
  116. package/dist/utils/isValidRecipient.js +22 -0
  117. package/dist/utils/isValidRecipient.js.map +1 -0
  118. package/dist/utils/isValidSolanaRecipient.d.ts +3 -0
  119. package/dist/utils/isValidSolanaRecipient.d.ts.map +1 -0
  120. package/dist/utils/isValidSolanaRecipient.js +13 -0
  121. package/dist/utils/isValidSolanaRecipient.js.map +1 -0
  122. package/package.json +38 -2
@@ -7,6 +7,17 @@ export type SolanaCoingeckoTokenResponse = {
7
7
  };
8
8
  };
9
9
  };
10
+ /** CoinGecko's on-chain multi-token lookup; a mint it does not index is simply missing from `data`. */
11
+ export type SolanaCoingeckoTokensResponse = {
12
+ data?: {
13
+ id: string;
14
+ type: 'token';
15
+ attributes?: {
16
+ address?: string;
17
+ coingecko_coin_id?: string | null;
18
+ };
19
+ }[];
20
+ };
10
21
  export type SolanaFmTokenResponse = {
11
22
  tokenList?: {
12
23
  extensions?: {
@@ -1 +1 @@
1
- {"version":3,"file":"coingeckoToken.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/coingecko/coingeckoToken.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,OAAO,CAAA;QACb,UAAU,EAAE;YACV,iBAAiB,EAAE,MAAM,CAAA;SAC1B,CAAA;KACF,CAAA;CACF,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE;QACV,UAAU,CAAC,EAAE;YACX,WAAW,CAAC,EAAE,MAAM,CAAA;SACrB,GAAG,IAAI,CAAA;KACT,GAAG,IAAI,CAAA;CACT,CAAA"}
1
+ {"version":3,"file":"coingeckoToken.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/coingecko/coingeckoToken.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,OAAO,CAAA;QACb,UAAU,EAAE;YACV,iBAAiB,EAAE,MAAM,CAAA;SAC1B,CAAA;KACF,CAAA;CACF,CAAA;AAED,uGAAuG;AACvG,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,OAAO,CAAA;QACb,UAAU,CAAC,EAAE;YACX,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAClC,CAAA;KACF,EAAE,CAAA;CACJ,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE;QACV,UAAU,CAAC,EAAE;YACX,WAAW,CAAC,EAAE,MAAM,CAAA;SACrB,GAAG,IAAI,CAAA;KACT,GAAG,IAAI,CAAA;CACT,CAAA"}
@@ -1,4 +1,14 @@
1
1
  export declare const getSolanaCoingeckoId: ({ id }: {
2
2
  id: string;
3
3
  }) => Promise<string | undefined>;
4
+ /**
5
+ * CoinGecko ids for the given mints, keyed by mint, read from CoinGecko's
6
+ * on-chain index thirty mints per call. Mints are matched exactly: base58 is
7
+ * case-sensitive and CoinGecko echoes the on-chain spelling. A mint it does
8
+ * not index, or lists without a coin id, is absent from the result. A failed
9
+ * call propagates instead of degrading to "no id": a caller that persists the
10
+ * answer would otherwise store a priced token as unpriced for good, whereas a
11
+ * failed call can simply be retried.
12
+ */
13
+ export declare const getSolanaCoingeckoIds: (ids: string[]) => Promise<Record<string, string>>;
4
14
  //# sourceMappingURL=getCoingeckoId.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getCoingeckoId.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/coingecko/getCoingeckoId.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,GAAU,QAAQ;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,gCAgBhE,CAAA"}
1
+ {"version":3,"file":"getCoingeckoId.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/coingecko/getCoingeckoId.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,oBAAoB,GAAU,QAAQ;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,gCAchE,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAAU,KAAK,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBzF,CAAA"}
@@ -1,8 +1,13 @@
1
1
  import { rootApiUrl } from '@vultisig/core-config';
2
+ import { toBatches } from '@vultisig/lib-utils/array/toBatches';
3
+ import { withoutDuplicates } from '@vultisig/lib-utils/array/withoutDuplicates';
2
4
  import { attempt } from '@vultisig/lib-utils/attempt';
3
5
  import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
6
+ const onchainSolanaTokensUrl = `${rootApiUrl}/coingeicko/api/v3/onchain/networks/solana/tokens`;
7
+ /** CoinGecko documents up to thirty addresses per multi-token call. */
8
+ const mintsPerLookup = 30;
4
9
  export const getSolanaCoingeckoId = async ({ id }) => {
5
- const cgResult = await attempt(() => queryUrl(`${rootApiUrl}/coingeicko/api/v3/onchain/networks/solana/tokens/${id}`));
10
+ const cgResult = await attempt(() => queryUrl(`${onchainSolanaTokensUrl}/${id}`));
6
11
  if ('data' in cgResult) {
7
12
  const coingeckoId = cgResult.data?.data?.attributes?.coingecko_coin_id ?? undefined;
8
13
  if (coingeckoId)
@@ -16,4 +21,28 @@ export const getSolanaCoingeckoId = async ({ id }) => {
16
21
  }
17
22
  return undefined;
18
23
  };
24
+ /**
25
+ * CoinGecko ids for the given mints, keyed by mint, read from CoinGecko's
26
+ * on-chain index thirty mints per call. Mints are matched exactly: base58 is
27
+ * case-sensitive and CoinGecko echoes the on-chain spelling. A mint it does
28
+ * not index, or lists without a coin id, is absent from the result. A failed
29
+ * call propagates instead of degrading to "no id": a caller that persists the
30
+ * answer would otherwise store a priced token as unpriced for good, whereas a
31
+ * failed call can simply be retried.
32
+ */
33
+ export const getSolanaCoingeckoIds = async (ids) => {
34
+ const requested = withoutDuplicates(ids);
35
+ const wanted = new Set(requested);
36
+ const responses = await Promise.all(toBatches(requested, mintsPerLookup).map(batch => queryUrl(`${onchainSolanaTokensUrl}/multi/${batch.join(',')}`)));
37
+ const result = {};
38
+ for (const { data } of responses) {
39
+ for (const { attributes } of data ?? []) {
40
+ const address = attributes?.address;
41
+ if (address && wanted.has(address) && attributes.coingecko_coin_id) {
42
+ result[address] = attributes.coingecko_coin_id;
43
+ }
44
+ }
45
+ }
46
+ return result;
47
+ };
19
48
  //# sourceMappingURL=getCoingeckoId.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getCoingeckoId.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/coingecko/getCoingeckoId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAI7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,EAAE,EAAE,EAAkB,EAAE,EAAE;IACnE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAClC,QAAQ,CAA+B,GAAG,UAAU,qDAAqD,EAAE,EAAE,CAAC,CAC/G,CAAA;IACD,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,iBAAiB,IAAI,SAAS,CAAA;QACnF,IAAI,WAAW;YAAE,OAAO,WAAW,CAAA;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAwB,mCAAmC,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9G,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAA;QAC9D,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;IACvB,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA"}
1
+ {"version":3,"file":"getCoingeckoId.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/coingecko/getCoingeckoId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAI7D,MAAM,sBAAsB,GAAG,GAAG,UAAU,mDAAmD,CAAA;AAE/F,uEAAuE;AACvE,MAAM,cAAc,GAAG,EAAE,CAAA;AAEzB,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,EAAE,EAAE,EAAkB,EAAE,EAAE;IACnE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAA+B,GAAG,sBAAsB,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;IAC/G,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,iBAAiB,IAAI,SAAS,CAAA;QACnF,IAAI,WAAW;YAAE,OAAO,WAAW,CAAA;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAwB,mCAAmC,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9G,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAA;QAC9D,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;IACvB,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EAAE,GAAa,EAAmC,EAAE;IAC5F,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IAEjC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAC/C,QAAQ,CAAgC,GAAG,sBAAsB,UAAU,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAC9F,CACF,CAAA;IAED,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,UAAU,EAAE,OAAO,CAAA;YACnC,IAAI,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,iBAAiB,EAAE,CAAC;gBACnE,MAAM,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,iBAAiB,CAAA;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
@@ -1,3 +1,24 @@
1
+ import { OtherChain } from '@vultisig/core-chain/Chain';
1
2
  import { FindCoinsResolver } from '@vultisig/core-chain/coin/find/resolver';
2
- export declare const findSolanaCoins: FindCoinsResolver;
3
+ /**
4
+ * Discovers the SPL and Token-2022 holdings at `address` that pass verification.
5
+ *
6
+ * Only `verified` mints are returned. Solana wallets are carpet-bombed with
7
+ * airdropped counterfeits and zero-decimal spam, and auto-adding those to a
8
+ * vault would put a "USDT" balance on the home screen that the user never
9
+ * received. A verified token is returned whether or not a price id is known
10
+ * for it: gating on price hid legitimate unpriced tokens while letting priced
11
+ * scams through. Unverified and scam mints can still be added by hand, where
12
+ * the UI labels them.
13
+ *
14
+ * Jupiter answers for a hundred mints per call and CoinGecko for thirty, so a
15
+ * whole wallet costs a handful of calls; decimals come from the token account
16
+ * itself, and curated metadata wins for tokens we ship ourselves. When Jupiter
17
+ * cannot be reached, listed mints are still discovered from registry metadata
18
+ * and only a mint verified since the registry's last refresh waits for the
19
+ * next round. A failed price-id lookup, by contrast, fails the round: the
20
+ * caller persists the result, and a token saved without its price id would
21
+ * stay unpriced for good.
22
+ */
23
+ export declare const findSolanaCoins: FindCoinsResolver<OtherChain.Solana>;
3
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/find/resolvers/solana/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAA;AAO3E,eAAO,MAAM,eAAe,EAAE,iBAiB7B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/find/resolvers/solana/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAMvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAA;AAkB3E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,eAAe,EAAE,iBAAiB,CAAC,UAAU,CAAC,MAAM,CAgEhE,CAAA"}
@@ -1,18 +1,86 @@
1
1
  import { getSplAccounts } from '@vultisig/core-chain/chains/solana/spl/getSplAccounts';
2
+ import { resolveSolanaTokenVerification } from '@vultisig/core-chain/chains/solana/spl/verification';
3
+ import { getSolanaVerifiedTokenRegistry } from '@vultisig/core-chain/chains/solana/spl/verifiedRegistry';
4
+ import { getSolanaCoingeckoIds } from '@vultisig/core-chain/coin/coingecko/getCoingeckoId';
5
+ import { getJupiterTokens } from '@vultisig/core-chain/coin/jupiter/api';
6
+ import { knownTokensIndex } from '@vultisig/core-chain/coin/knownTokens';
2
7
  import { without } from '@vultisig/lib-utils/array/without';
3
8
  import { attempt } from '@vultisig/lib-utils/attempt';
4
- import { Chain } from '../../../../Chain.js';
5
- import { getSolanaTokenMetadata } from '../../../token/metadata/resolvers/solana.js';
6
- export const findSolanaCoins = async ({ address }) => {
9
+ const toHolding = (account) => {
10
+ const { mint, tokenAmount } = account.account.data.parsed.info;
11
+ return { mint: String(mint), amount: BigInt(tokenAmount.amount), decimals: Number(tokenAmount.decimals) };
12
+ };
13
+ /**
14
+ * Discovers the SPL and Token-2022 holdings at `address` that pass verification.
15
+ *
16
+ * Only `verified` mints are returned. Solana wallets are carpet-bombed with
17
+ * airdropped counterfeits and zero-decimal spam, and auto-adding those to a
18
+ * vault would put a "USDT" balance on the home screen that the user never
19
+ * received. A verified token is returned whether or not a price id is known
20
+ * for it: gating on price hid legitimate unpriced tokens while letting priced
21
+ * scams through. Unverified and scam mints can still be added by hand, where
22
+ * the UI labels them.
23
+ *
24
+ * Jupiter answers for a hundred mints per call and CoinGecko for thirty, so a
25
+ * whole wallet costs a handful of calls; decimals come from the token account
26
+ * itself, and curated metadata wins for tokens we ship ourselves. When Jupiter
27
+ * cannot be reached, listed mints are still discovered from registry metadata
28
+ * and only a mint verified since the registry's last refresh waits for the
29
+ * next round. A failed price-id lookup, by contrast, fails the round: the
30
+ * caller persists the result, and a token saved without its price id would
31
+ * stay unpriced for good.
32
+ */
33
+ export const findSolanaCoins = async ({ address, chain }) => {
7
34
  const accounts = await getSplAccounts(address);
8
- const tokenAddresses = accounts.map(account => account.account.data.parsed.info.mint);
9
- const result = await Promise.all(tokenAddresses.map(async (id) => {
10
- const key = { id, chain: Chain.Solana };
11
- const { data } = await attempt(getSolanaTokenMetadata(key));
12
- if (data && data.priceProviderId) {
13
- return { ...key, ...data, address };
35
+ const holdings = new Map();
36
+ for (const account of accounts) {
37
+ const holding = toHolding(account);
38
+ if (holding.amount > 0n && !holdings.has(holding.mint))
39
+ holdings.set(holding.mint, holding);
40
+ }
41
+ if (holdings.size === 0)
42
+ return [];
43
+ const mints = [...holdings.keys()];
44
+ const [jupiter, registry] = await Promise.all([attempt(getJupiterTokens(mints)), getSolanaVerifiedTokenRegistry()]);
45
+ if ('error' in jupiter) {
46
+ console.warn('[solana] Jupiter metadata unavailable; discovering registry-listed mints only', jupiter.error);
47
+ }
48
+ const tokens = 'data' in jupiter && jupiter.data ? jupiter.data : {};
49
+ const verified = [...holdings.values()].filter(({ mint }) => {
50
+ const token = tokens[mint];
51
+ const verification = resolveSolanaTokenVerification({
52
+ address: mint,
53
+ symbol: token?.symbol,
54
+ name: token?.name,
55
+ isVerified: token?.isVerified,
56
+ registry,
57
+ });
58
+ return verification === 'verified';
59
+ });
60
+ const getKnown = (mint) => knownTokensIndex[chain][mint.toLowerCase()];
61
+ const priceProviderIds = await getSolanaCoingeckoIds(verified.filter(({ mint }) => !getKnown(mint)).map(({ mint }) => mint));
62
+ const coins = verified.map(({ mint: id, decimals }) => {
63
+ const known = getKnown(id);
64
+ if (known) {
65
+ return { ...known, chain, id, address };
14
66
  }
15
- }));
16
- return without(result, undefined);
67
+ const token = tokens[id];
68
+ const listed = registry.byAddress[id];
69
+ const ticker = token?.symbol ?? listed?.symbol;
70
+ if (!ticker)
71
+ return;
72
+ const logo = token?.icon ?? listed?.logo;
73
+ const priceProviderId = priceProviderIds[id];
74
+ return {
75
+ chain,
76
+ id,
77
+ address,
78
+ ticker,
79
+ decimals,
80
+ ...(logo === undefined ? {} : { logo }),
81
+ ...(priceProviderId === undefined ? {} : { priceProviderId }),
82
+ };
83
+ });
84
+ return without(coins, undefined);
17
85
  };
18
86
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/find/resolvers/solana/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAA;AAEtF,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAErD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AAEjF,MAAM,CAAC,MAAM,eAAe,GAAsB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACtE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;IAE9C,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAErF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,cAAc,CAAC,GAAG,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE;QAC5B,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAW,CAAA;QAChD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAA;QAE3D,IAAI,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACjC,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAA;QACrC,CAAC;IACH,CAAC,CAAC,CACH,CAAA;IAED,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AACnC,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/find/resolvers/solana/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { SolanaJupiterToken } from '@vultisig/core-chain/coin/jupiter/token';
2
+ /** Jupiter's Token API v2, reached through the Vultisig proxy. */
3
+ export declare const baseJupiterTokensUrl: string;
4
+ /**
5
+ * Metadata for the given mints, keyed by mint. One search call covers a
6
+ * hundred mints, so a whole wallet costs a call or two rather than one per
7
+ * token. A mint Jupiter does not index is simply absent from the result, and
8
+ * the response is filtered to the requested mints so a lookalike match can
9
+ * never stand in for a mint that was asked about.
10
+ */
11
+ export declare const getJupiterTokens: (mints: string[]) => Promise<Record<string, SolanaJupiterToken>>;
12
+ /**
13
+ * Every mint Jupiter marks verified: the community-reviewed list the major
14
+ * Solana wallets show as their "verified" tier. Several megabytes, so callers
15
+ * cache it.
16
+ */
17
+ export declare const getJupiterVerifiedTokens: () => Promise<SolanaJupiterToken[]>;
18
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/jupiter/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAM5E,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,QAAgC,CAAA;AA6BjE;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,OAAO,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAkBlG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,kBAAkB,EAAE,CAI3E,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { rootApiUrl } from '@vultisig/core-config';
2
+ import { toBatches } from '@vultisig/lib-utils/array/toBatches';
3
+ import { withoutDuplicates } from '@vultisig/lib-utils/array/withoutDuplicates';
4
+ import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
5
+ /** Jupiter's Token API v2, reached through the Vultisig proxy. */
6
+ export const baseJupiterTokensUrl = `${rootApiUrl}/jup/tokens/v2`;
7
+ /** Jupiter's search endpoint accepts up to a hundred comma-separated mints per call. */
8
+ const mintsPerSearch = 100;
9
+ // The verified list runs to several megabytes; a slow link should not turn it
10
+ // into a timeout, which would leave legitimate tokens unrecognised until retry.
11
+ const verifiedListTimeoutMs = 60_000;
12
+ const isJupiterToken = (value) => {
13
+ if (typeof value !== 'object' || value === null)
14
+ return false;
15
+ const { id, symbol, name, decimals } = value;
16
+ return (typeof id === 'string' && typeof symbol === 'string' && typeof name === 'string' && typeof decimals === 'number');
17
+ };
18
+ // An entry missing a required field is dropped rather than passed on as a
19
+ // partial token that would surface as `decimals: undefined` downstream.
20
+ const parseJupiterTokens = (response, source) => {
21
+ if (!Array.isArray(response)) {
22
+ throw new Error(`Jupiter ${source} did not return a token list`);
23
+ }
24
+ return response.filter(isJupiterToken);
25
+ };
26
+ /**
27
+ * Metadata for the given mints, keyed by mint. One search call covers a
28
+ * hundred mints, so a whole wallet costs a call or two rather than one per
29
+ * token. A mint Jupiter does not index is simply absent from the result, and
30
+ * the response is filtered to the requested mints so a lookalike match can
31
+ * never stand in for a mint that was asked about.
32
+ */
33
+ export const getJupiterTokens = async (mints) => {
34
+ const requested = withoutDuplicates(mints);
35
+ const wanted = new Set(requested);
36
+ const responses = await Promise.all(toBatches(requested, mintsPerSearch).map(batch => queryUrl(`${baseJupiterTokensUrl}/search?query=${batch.join(',')}`)));
37
+ const result = {};
38
+ for (const response of responses) {
39
+ for (const token of parseJupiterTokens(response, 'search')) {
40
+ if (wanted.has(token.id))
41
+ result[token.id] = token;
42
+ }
43
+ }
44
+ return result;
45
+ };
46
+ /**
47
+ * Every mint Jupiter marks verified: the community-reviewed list the major
48
+ * Solana wallets show as their "verified" tier. Several megabytes, so callers
49
+ * cache it.
50
+ */
51
+ export const getJupiterVerifiedTokens = async () => parseJupiterTokens(await queryUrl(`${baseJupiterTokensUrl}/tag?query=verified`, { timeoutMs: verifiedListTimeoutMs }), 'verified list');
52
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/jupiter/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,kEAAkE;AAClE,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,UAAU,gBAAgB,CAAA;AAEjE,wFAAwF;AACxF,MAAM,cAAc,GAAG,GAAG,CAAA;AAE1B,8EAA8E;AAC9E,gFAAgF;AAChF,MAAM,qBAAqB,GAAG,MAAM,CAAA;AAEpC,MAAM,cAAc,GAAG,CAAC,KAAc,EAA+B,EAAE;IACrE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAE7D,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAgC,CAAA;IAEvE,OAAO,CACL,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,CACjH,CAAA;AACH,CAAC,CAAA;AAED,0EAA0E;AAC1E,wEAAwE;AACxE,MAAM,kBAAkB,GAAG,CAAC,QAAiB,EAAE,MAAc,EAAwB,EAAE;IACrF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,8BAA8B,CAAC,CAAA;IAClE,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;AACxC,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,KAAe,EAA+C,EAAE;IACrG,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IAEjC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAC/C,QAAQ,CAAU,GAAG,oBAAoB,iBAAiB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAC7E,CACF,CAAA;IAED,MAAM,MAAM,GAAuC,EAAE,CAAA;IACrD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC3D,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAA;QACpD,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,IAAmC,EAAE,CAChF,kBAAkB,CAChB,MAAM,QAAQ,CAAU,GAAG,oBAAoB,qBAAqB,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,EAC3G,eAAe,CAChB,CAAA"}
@@ -1,11 +1,15 @@
1
1
  import { Chain } from '@vultisig/core-chain/Chain';
2
2
  import { Coin } from '@vultisig/core-chain/coin/Coin';
3
+ /** One entry of Jupiter's Token API v2, as returned by its search and tag endpoints. */
3
4
  export type SolanaJupiterToken = {
4
5
  id: string;
5
6
  name: string;
6
7
  symbol: string;
7
8
  decimals: number;
8
9
  icon?: string;
10
+ /** Jupiter's own verification flag; `null` for a mint it indexes but does not vouch for. */
11
+ isVerified?: boolean | null;
12
+ tags?: string[];
9
13
  };
10
14
  type FromSolanaJupiterTokensInput = {
11
15
  tokens: SolanaJupiterToken[];
@@ -1 +1 @@
1
- {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/jupiter/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAA;AAErD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,4BAA4B,GAAG;IAClC,MAAM,EAAE,kBAAkB,EAAE,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAA;CACb,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,mBAAmB,4BAA4B,KAAG,IAAI,EAU7F,CAAA"}
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/jupiter/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAA;AAErD,wFAAwF;AACxF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4FAA4F;IAC5F,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAED,KAAK,4BAA4B,GAAG;IAClC,MAAM,EAAE,kBAAkB,EAAE,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAA;CACb,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,mBAAmB,4BAA4B,KAAG,IAAI,EAU7F,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/jupiter/token.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,EAAgC,EAAU,EAAE;IACjG,OAAO,MAAM;SACV,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,6CAA6C;SAC3E,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACb,KAAK;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC,CAAA;AACP,CAAC,CAAA"}
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/jupiter/token.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,EAAgC,EAAU,EAAE;IACjG,OAAO,MAAM;SACV,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,6CAA6C;SAC3E,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACb,KAAK;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC,CAAA;AACP,CAAC,CAAA"}
@@ -1,4 +1,6 @@
1
+ import { baseJupiterTokensUrl } from '@vultisig/core-chain/coin/jupiter/api';
1
2
  import { TokenMetadataResolver } from '../resolver.js';
2
- export declare const baseJupiterTokensUrl = "https://api.vultisig.com/jup/tokens/v2";
3
+ /** Kept on this subpath for consumers that read the Jupiter base URL from the resolver module. */
4
+ export { baseJupiterTokensUrl };
3
5
  export declare const getSolanaTokenMetadata: TokenMetadataResolver;
4
6
  //# sourceMappingURL=solana.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/token/metadata/resolvers/solana.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,eAAO,MAAM,oBAAoB,2CAA2C,CAAA;AAE5E,eAAO,MAAM,sBAAsB,EAAE,qBAYpC,CAAA"}
1
+ {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/token/metadata/resolvers/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAoB,MAAM,uCAAuC,CAAA;AAG9F,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,kGAAkG;AAClG,OAAO,EAAE,oBAAoB,EAAE,CAAA;AAE/B,eAAO,MAAM,sBAAsB,EAAE,qBAcpC,CAAA"}
@@ -1,13 +1,17 @@
1
- import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
1
+ import { baseJupiterTokensUrl, getJupiterTokens } from '@vultisig/core-chain/coin/jupiter/api';
2
2
  import { getSolanaCoingeckoId } from '../../../coingecko/getCoingeckoId.js';
3
- export const baseJupiterTokensUrl = 'https://api.vultisig.com/jup/tokens/v2';
3
+ /** Kept on this subpath for consumers that read the Jupiter base URL from the resolver module. */
4
+ export { baseJupiterTokensUrl };
4
5
  export const getSolanaTokenMetadata = async ({ id }) => {
5
- const [{ decimals, icon, symbol }] = await queryUrl(`${baseJupiterTokensUrl}/search?query=${id}`);
6
+ const token = (await getJupiterTokens([id]))[id];
7
+ if (!token) {
8
+ throw new Error(`Jupiter has no metadata for Solana mint ${id}`);
9
+ }
6
10
  const coingeckoId = await getSolanaCoingeckoId({ id });
7
11
  return {
8
- decimals,
9
- logo: icon,
10
- ticker: symbol,
12
+ decimals: token.decimals,
13
+ logo: token.icon,
14
+ ticker: token.symbol,
11
15
  priceProviderId: coingeckoId,
12
16
  };
13
17
  };
@@ -1 +1 @@
1
- {"version":3,"file":"solana.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/token/metadata/resolvers/solana.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAGxE,MAAM,CAAC,MAAM,oBAAoB,GAAG,wCAAwC,CAAA;AAE5E,MAAM,CAAC,MAAM,sBAAsB,GAA0B,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IAC5E,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,QAAQ,CACjD,GAAG,oBAAoB,iBAAiB,EAAE,EAAE,CAC7C,CAAA;IACD,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAEtD,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,WAAW;KAC7B,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"solana.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/coin/token/metadata/resolvers/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AAE9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAGxE,kGAAkG;AAClG,OAAO,EAAE,oBAAoB,EAAE,CAAA;AAE/B,MAAM,CAAC,MAAM,sBAAsB,GAA0B,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IAC5E,MAAM,KAAK,GAAG,CAAC,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAChD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,2CAA2C,EAAE,EAAE,CAAC,CAAA;IAClE,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAEtD,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,eAAe,EAAE,WAAW;KAC7B,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Collapses a token symbol or name to the Latin skeleton a user perceives, so
3
+ * `USD₮`, `UЅDT` (Cyrillic Ѕ), `$USĐ₮` and `usdt` all compare equal to `USDT`.
4
+ * Compatibility decomposition folds full-width and mathematical letter forms,
5
+ * diacritics are dropped, known homoglyphs are mapped, and everything that is
6
+ * not `A–Z`/`0–9` is removed. Returns an empty string when nothing survives.
7
+ * Chain-agnostic: every chain's counterfeit heuristic compares these skeletons.
8
+ */
9
+ export declare const normalizeTokenSymbol: (value: string) => string;
10
+ //# sourceMappingURL=tokenSymbol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenSymbol.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/coin/tokenSymbol.ts"],"names":[],"mappings":"AAmDA;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MAIvB,CAAA"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Homoglyphs scammers substitute into a token symbol so it *reads* like a
3
+ * verified one while differing byte-for-byte: Cyrillic/Greek capitals that look
4
+ * like Latin ones, the tugrik sign standing in for `T`, and stroked `D`s. Keys
5
+ * are already upper-cased because the map is applied after `toUpperCase()`.
6
+ */
7
+ const confusables = {
8
+ // Cyrillic
9
+ А: 'A',
10
+ В: 'B',
11
+ Е: 'E',
12
+ Ё: 'E',
13
+ Ѕ: 'S',
14
+ І: 'I',
15
+ Ј: 'J',
16
+ К: 'K',
17
+ М: 'M',
18
+ Н: 'H',
19
+ О: 'O',
20
+ Р: 'P',
21
+ С: 'C',
22
+ Т: 'T',
23
+ У: 'Y',
24
+ Х: 'X',
25
+ Ԛ: 'Q',
26
+ Ԝ: 'W',
27
+ // Greek
28
+ Α: 'A',
29
+ Β: 'B',
30
+ Ε: 'E',
31
+ Ζ: 'Z',
32
+ Η: 'H',
33
+ Ι: 'I',
34
+ Κ: 'K',
35
+ Μ: 'M',
36
+ Ν: 'N',
37
+ Ο: 'O',
38
+ Ρ: 'P',
39
+ Τ: 'T',
40
+ Υ: 'Y',
41
+ Χ: 'X',
42
+ // Currency and stroked letters
43
+ '₮': 'T',
44
+ Đ: 'D',
45
+ Ð: 'D',
46
+ Ɖ: 'D',
47
+ Ŧ: 'T',
48
+ };
49
+ const combiningMarks = /[̀-ͯ]/g;
50
+ /**
51
+ * Collapses a token symbol or name to the Latin skeleton a user perceives, so
52
+ * `USD₮`, `UЅDT` (Cyrillic Ѕ), `$USĐ₮` and `usdt` all compare equal to `USDT`.
53
+ * Compatibility decomposition folds full-width and mathematical letter forms,
54
+ * diacritics are dropped, known homoglyphs are mapped, and everything that is
55
+ * not `A–Z`/`0–9` is removed. Returns an empty string when nothing survives.
56
+ * Chain-agnostic: every chain's counterfeit heuristic compares these skeletons.
57
+ */
58
+ export const normalizeTokenSymbol = (value) => Array.from(value.normalize('NFKD').replace(combiningMarks, '').toUpperCase())
59
+ .map(char => confusables[char] ?? char)
60
+ .join('')
61
+ .replace(/[^A-Z0-9]/g, '');
62
+ //# sourceMappingURL=tokenSymbol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenSymbol.js","sourceRoot":"","sources":["../../../../../packages/core/chain/coin/tokenSymbol.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,GAA2B;IAC1C,WAAW;IACX,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,QAAQ;IACR,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,+BAA+B;IAC/B,GAAG,EAAE,GAAG;IACR,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;IACN,CAAC,EAAE,GAAG;CACP,CAAA;AAED,MAAM,cAAc,GAAG,QAAQ,CAAA;AAE/B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAU,EAAE,CAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;KAC1E,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;KACtC,IAAI,CAAC,EAAE,CAAC;KACR,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA"}
@@ -9,6 +9,7 @@ export declare const blockaidEvmChain: {
9
9
  readonly Mantle: "mantle";
10
10
  readonly Optimism: "optimism";
11
11
  readonly Polygon: "polygon";
12
+ readonly Robinhood: "robinhood";
12
13
  readonly Sei: "sei";
13
14
  readonly Zksync: "zksync";
14
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"evmChains.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/security/blockaid/evmChains.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;CAenB,CAAA;AAEV,MAAM,MAAM,yBAAyB,GAAG,MAAM,OAAO,gBAAgB,CAAA;AAErE,eAAO,MAAM,0BAA0B,EAAoC,yBAAyB,EAAE,CAAA"}
1
+ {"version":3,"file":"evmChains.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/security/blockaid/evmChains.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;CAgBnB,CAAA;AAEV,MAAM,MAAM,yBAAyB,GAAG,MAAM,OAAO,gBAAgB,CAAA;AAErE,eAAO,MAAM,0BAA0B,EAAoC,yBAAyB,EAAE,CAAA"}
@@ -10,10 +10,11 @@ export const blockaidEvmChain = {
10
10
  [EvmChain.Mantle]: 'mantle',
11
11
  [EvmChain.Optimism]: 'optimism',
12
12
  [EvmChain.Polygon]: 'polygon',
13
+ [EvmChain.Robinhood]: 'robinhood',
13
14
  [EvmChain.Sei]: 'sei',
14
15
  [EvmChain.Zksync]: 'zksync',
15
- // Robinhood (4663) deliberately absent: Blockaid does not list the chain
16
- // yet (same posture as CronosChain). Recheck when Blockaid adds support.
16
+ // CronosChain deliberately absent: Blockaid rejects `cronos` as not
17
+ // supported in GA. Recheck against the live endpoint before adding it.
17
18
  };
18
19
  export const blockaidSupportedEvmChains = Object.keys(blockaidEvmChain);
19
20
  //# sourceMappingURL=evmChains.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evmChains.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/security/blockaid/evmChains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC/B,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW;IACjC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IACvB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IACzB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK;IACrB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC/B,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,UAAU;IAClC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ;IAC3B,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC/B,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;IAC7B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK;IACrB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ;IAC3B,yEAAyE;IACzE,yEAAyE;CACjE,CAAA;AAIV,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAgC,CAAA"}
1
+ {"version":3,"file":"evmChains.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/security/blockaid/evmChains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC/B,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW;IACjC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IACvB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IACzB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK;IACrB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC/B,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,UAAU;IAClC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ;IAC3B,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU;IAC/B,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;IAC7B,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW;IACjC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK;IACrB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ;IAC3B,oEAAoE;IACpE,uEAAuE;CAC/D,CAAA;AAIV,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAgC,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { OtherChain } from '../../Chain.js';
2
2
  import { DeriveChainKind } from '../../ChainKind.js';
3
- export declare const blockaidSimulationSupportedChains: readonly [...("Arbitrum" | "Base" | "Blast" | "Optimism" | "Zksync" | "Mantle" | "Avalanche" | "BSC" | "Ethereum" | "Polygon" | "Hyperliquid" | "Sei")[], OtherChain.Solana, OtherChain.Sui];
3
+ export declare const blockaidSimulationSupportedChains: readonly [...("Arbitrum" | "Base" | "Blast" | "Optimism" | "Zksync" | "Mantle" | "Robinhood" | "Avalanche" | "BSC" | "Ethereum" | "Polygon" | "Hyperliquid" | "Sei")[], OtherChain.Solana, OtherChain.Sui];
4
4
  export type BlockaidSimulationSupportedChain = (typeof blockaidSimulationSupportedChains)[number];
5
5
  export type BlockaidSimulationSupportedChainKind = DeriveChainKind<BlockaidSimulationSupportedChain>;
6
6
  //# sourceMappingURL=simulationChains.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"simulationChains.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/security/blockaid/simulationChains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGjD,eAAO,MAAM,iCAAiC,8LAIpC,CAAA;AAEV,MAAM,MAAM,gCAAgC,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,MAAM,CAAC,CAAA;AACjG,MAAM,MAAM,oCAAoC,GAAG,eAAe,CAAC,gCAAgC,CAAC,CAAA"}
1
+ {"version":3,"file":"simulationChains.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/security/blockaid/simulationChains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGjD,eAAO,MAAM,iCAAiC,4MAIpC,CAAA;AAEV,MAAM,MAAM,gCAAgC,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,MAAM,CAAC,CAAA;AACjG,MAAM,MAAM,oCAAoC,GAAG,eAAe,CAAC,gCAAgC,CAAC,CAAA"}
@@ -114,6 +114,23 @@ export type BlockaidEVMSimulation = {
114
114
  }>;
115
115
  };
116
116
  };
117
+ /**
118
+ * Parse a Blockaid Solana simulation into the user's net balance change,
119
+ * classified as a `swap` (two distinct mints move) or a `transfer` (one
120
+ * mint moves net-negative).
121
+ *
122
+ * Diffs are grouped by resolved mint and netted (`in - out`) per group,
123
+ * mirroring `parseBlockaidEvmSimulation`. This collapses a wrap-then-spend or
124
+ * an unwrap/close-account pair — native SOL and the WSOL mint landing in the
125
+ * same bucket — into the single net movement it actually is, instead of
126
+ * surfacing a same-asset "SOL -> WSOL swap" whose destination amount is only
127
+ * the token account's rent-exempt residual (sdk#1997).
128
+ *
129
+ * Throws when the netted result isn't representable as `swap`/`transfer`
130
+ * (net-zero, a pure net-receive with no matching type, or 3+ distinct
131
+ * nonzero mints) rather than guess — the caller falls back to showing no
132
+ * preview, which is safe; a wrong number is not.
133
+ */
117
134
  export declare const parseBlockaidSolanaSimulation: (simulation: BlockaidSolanaSimulation) => Promise<BlockaidSolanaSimulationInfo>;
118
135
  /**
119
136
  * Parse a Blockaid EVM simulation into the user's net balance changes.
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/chain/security/blockaid/tx/simulation/api/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/chain/security/blockaid/tx/simulation/api/core.ts"],"names":[],"mappings":"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"}