@vultisig/core-chain 4.1.1 → 5.1.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 (157) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/dist/Chain.d.ts +0 -4
  3. package/dist/Chain.d.ts.map +1 -1
  4. package/dist/Chain.js +0 -1
  5. package/dist/Chain.js.map +1 -1
  6. package/dist/ChainKind.d.ts +0 -1
  7. package/dist/ChainKind.d.ts.map +1 -1
  8. package/dist/ChainKind.js +0 -1
  9. package/dist/ChainKind.js.map +1 -1
  10. package/dist/chainRegistry.d.ts +0 -1
  11. package/dist/chainRegistry.d.ts.map +1 -1
  12. package/dist/chainRegistry.js +0 -1
  13. package/dist/chainRegistry.js.map +1 -1
  14. package/dist/chains/cosmos/account/getCosmosAccountInfo.d.ts.map +1 -1
  15. package/dist/chains/cosmos/account/getCosmosAccountInfo.js +0 -5
  16. package/dist/chains/cosmos/account/getCosmosAccountInfo.js.map +1 -1
  17. package/dist/chains/cosmos/chainInfo.d.ts.map +1 -1
  18. package/dist/chains/cosmos/chainInfo.js +0 -1
  19. package/dist/chains/cosmos/chainInfo.js.map +1 -1
  20. package/dist/chains/cosmos/cosmosFeeCoinDenom.d.ts.map +1 -1
  21. package/dist/chains/cosmos/cosmosFeeCoinDenom.js +0 -1
  22. package/dist/chains/cosmos/cosmosFeeCoinDenom.js.map +1 -1
  23. package/dist/chains/cosmos/cosmosGasLimitRecord.d.ts.map +1 -1
  24. package/dist/chains/cosmos/cosmosGasLimitRecord.js +0 -2
  25. package/dist/chains/cosmos/cosmosGasLimitRecord.js.map +1 -1
  26. package/dist/chains/cosmos/cosmosMemoCap.d.ts.map +1 -1
  27. package/dist/chains/cosmos/cosmosMemoCap.js +0 -1
  28. package/dist/chains/cosmos/cosmosMemoCap.js.map +1 -1
  29. package/dist/chains/cosmos/cosmosRpcUrl.d.ts.map +1 -1
  30. package/dist/chains/cosmos/cosmosRpcUrl.js +0 -3
  31. package/dist/chains/cosmos/cosmosRpcUrl.js.map +1 -1
  32. package/dist/chains/cosmos/gas.d.ts.map +1 -1
  33. package/dist/chains/cosmos/gas.js +0 -1
  34. package/dist/chains/cosmos/gas.js.map +1 -1
  35. package/dist/chains/cosmos/tendermintRpcUrl.d.ts.map +1 -1
  36. package/dist/chains/cosmos/tendermintRpcUrl.js +0 -1
  37. package/dist/chains/cosmos/tendermintRpcUrl.js.map +1 -1
  38. package/dist/chains/cosmos/thor/thorchainLp.d.ts.map +1 -1
  39. package/dist/chains/cosmos/thor/thorchainLp.js +0 -1
  40. package/dist/chains/cosmos/thor/thorchainLp.js.map +1 -1
  41. package/dist/chains/ripple/issuedCurrency.d.ts +13 -3
  42. package/dist/chains/ripple/issuedCurrency.d.ts.map +1 -1
  43. package/dist/chains/ripple/issuedCurrency.js +65 -6
  44. package/dist/chains/ripple/issuedCurrency.js.map +1 -1
  45. package/dist/chains/ripple/trustLine.d.ts +22 -0
  46. package/dist/chains/ripple/trustLine.d.ts.map +1 -0
  47. package/dist/chains/ripple/trustLine.js +14 -0
  48. package/dist/chains/ripple/trustLine.js.map +1 -0
  49. package/dist/chains/ton/address.d.ts +32 -0
  50. package/dist/chains/ton/address.d.ts.map +1 -1
  51. package/dist/chains/ton/address.js +45 -0
  52. package/dist/chains/ton/address.js.map +1 -1
  53. package/dist/chains/ton/api.d.ts +49 -0
  54. package/dist/chains/ton/api.d.ts.map +1 -1
  55. package/dist/chains/ton/api.js +131 -24
  56. package/dist/chains/ton/api.js.map +1 -1
  57. package/dist/chains/ton/comment.d.ts +51 -0
  58. package/dist/chains/ton/comment.d.ts.map +1 -0
  59. package/dist/chains/ton/comment.js +75 -0
  60. package/dist/chains/ton/comment.js.map +1 -0
  61. package/dist/chains/ton/jetton/symbol.d.ts +9 -0
  62. package/dist/chains/ton/jetton/symbol.d.ts.map +1 -0
  63. package/dist/chains/ton/jetton/symbol.js +61 -0
  64. package/dist/chains/ton/jetton/symbol.js.map +1 -0
  65. package/dist/chains/ton/jetton/verification.d.ts +35 -0
  66. package/dist/chains/ton/jetton/verification.d.ts.map +1 -0
  67. package/dist/chains/ton/jetton/verification.js +45 -0
  68. package/dist/chains/ton/jetton/verification.js.map +1 -0
  69. package/dist/chains/ton/jetton/verifiedRegistry.d.ts +43 -0
  70. package/dist/chains/ton/jetton/verifiedRegistry.d.ts.map +1 -0
  71. package/dist/chains/ton/jetton/verifiedRegistry.js +94 -0
  72. package/dist/chains/ton/jetton/verifiedRegistry.js.map +1 -0
  73. package/dist/chains/ton/messageBounce.d.ts +17 -0
  74. package/dist/chains/ton/messageBounce.d.ts.map +1 -0
  75. package/dist/chains/ton/messageBounce.js +41 -0
  76. package/dist/chains/ton/messageBounce.js.map +1 -0
  77. package/dist/chains/tron/getTronBlockInfo.d.ts.map +1 -1
  78. package/dist/chains/tron/getTronBlockInfo.js +4 -5
  79. package/dist/chains/tron/getTronBlockInfo.js.map +1 -1
  80. package/dist/coin/balance/resolvers/ripple.d.ts.map +1 -1
  81. package/dist/coin/balance/resolvers/ripple.js +3 -2
  82. package/dist/coin/balance/resolvers/ripple.js.map +1 -1
  83. package/dist/coin/chainFeeCoin.d.ts.map +1 -1
  84. package/dist/coin/chainFeeCoin.js +0 -5
  85. package/dist/coin/chainFeeCoin.js.map +1 -1
  86. package/dist/coin/coinType.d.ts.map +1 -1
  87. package/dist/coin/coinType.js +0 -1
  88. package/dist/coin/coinType.js.map +1 -1
  89. package/dist/coin/find/CoinFinderChainKind.d.ts +1 -1
  90. package/dist/coin/find/CoinFinderChainKind.d.ts.map +1 -1
  91. package/dist/coin/find/CoinFinderChainKind.js +1 -1
  92. package/dist/coin/find/CoinFinderChainKind.js.map +1 -1
  93. package/dist/coin/find/index.d.ts.map +1 -1
  94. package/dist/coin/find/index.js +2 -0
  95. package/dist/coin/find/index.js.map +1 -1
  96. package/dist/coin/find/resolvers/ton.d.ts +15 -0
  97. package/dist/coin/find/resolvers/ton.d.ts.map +1 -0
  98. package/dist/coin/find/resolvers/ton.js +61 -0
  99. package/dist/coin/find/resolvers/ton.js.map +1 -0
  100. package/dist/coin/knownTokens/cosmos.d.ts.map +1 -1
  101. package/dist/coin/knownTokens/cosmos.js +0 -64
  102. package/dist/coin/knownTokens/cosmos.js.map +1 -1
  103. package/dist/coin/knownTokens/index.d.ts +1 -1
  104. package/dist/coin/knownTokens/index.d.ts.map +1 -1
  105. package/dist/coin/token/metadata/chains.d.ts +1 -1
  106. package/dist/coin/token/metadata/chains.d.ts.map +1 -1
  107. package/dist/coin/tokenVerification.d.ts +13 -0
  108. package/dist/coin/tokenVerification.d.ts.map +1 -0
  109. package/dist/coin/tokenVerification.js +12 -0
  110. package/dist/coin/tokenVerification.js.map +1 -0
  111. package/dist/swap/general/swapkit/SwapKitEnabledChains.d.ts +14 -3
  112. package/dist/swap/general/swapkit/SwapKitEnabledChains.d.ts.map +1 -1
  113. package/dist/swap/general/swapkit/SwapKitEnabledChains.js +14 -1
  114. package/dist/swap/general/swapkit/SwapKitEnabledChains.js.map +1 -1
  115. package/dist/swap/general/swapkit/SwapKitProviders.d.ts +19 -3
  116. package/dist/swap/general/swapkit/SwapKitProviders.d.ts.map +1 -1
  117. package/dist/swap/general/swapkit/SwapKitProviders.js +161 -8
  118. package/dist/swap/general/swapkit/SwapKitProviders.js.map +1 -1
  119. package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts +1 -3
  120. package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
  121. package/dist/swap/general/swapkit/api/getSwapKitQuote.js +148 -78
  122. package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
  123. package/dist/swap/general/swapkit/getSwapKitTrackerUrl.d.ts +2 -1
  124. package/dist/swap/general/swapkit/getSwapKitTrackerUrl.d.ts.map +1 -1
  125. package/dist/swap/general/swapkit/getSwapKitTrackerUrl.js +2 -1
  126. package/dist/swap/general/swapkit/getSwapKitTrackerUrl.js.map +1 -1
  127. package/dist/swap/native/NativeSwapChain.d.ts +1 -2
  128. package/dist/swap/native/NativeSwapChain.d.ts.map +1 -1
  129. package/dist/swap/native/NativeSwapChain.js +0 -2
  130. package/dist/swap/native/NativeSwapChain.js.map +1 -1
  131. package/dist/swap/native/limitSwapMemo.d.ts.map +1 -1
  132. package/dist/swap/native/limitSwapMemo.js +18 -5
  133. package/dist/swap/native/limitSwapMemo.js.map +1 -1
  134. package/dist/swap/native/thorchainMemoAsset.d.ts +1 -1
  135. package/dist/swap/native/thorchainMemoAsset.js +1 -1
  136. package/dist/swap/quote/findSwapQuote.d.ts.map +1 -1
  137. package/dist/swap/quote/findSwapQuote.js +2 -2
  138. package/dist/swap/quote/findSwapQuote.js.map +1 -1
  139. package/dist/swap/skip/skipRouting.d.ts.map +1 -1
  140. package/dist/swap/skip/skipRouting.js +0 -1
  141. package/dist/swap/skip/skipRouting.js.map +1 -1
  142. package/dist/swap/swapEnabledChains.d.ts +1 -1
  143. package/dist/swap/swapEnabledChains.d.ts.map +1 -1
  144. package/dist/tx/broadcast/resolvers/tron.d.ts.map +1 -1
  145. package/dist/tx/broadcast/resolvers/tron.js +6 -1
  146. package/dist/tx/broadcast/resolvers/tron.js.map +1 -1
  147. package/dist/tx/broadcast/verifyBroadcastByHash.js +1 -1
  148. package/dist/tx/broadcast/verifyBroadcastByHash.js.map +1 -1
  149. package/dist/tx/status/resolver.d.ts +9 -1
  150. package/dist/tx/status/resolver.d.ts.map +1 -1
  151. package/dist/tx/status/resolvers/ripple.d.ts.map +1 -1
  152. package/dist/tx/status/resolvers/ripple.js +62 -0
  153. package/dist/tx/status/resolvers/ripple.js.map +1 -1
  154. package/dist/tx/status/resolvers/tron.d.ts.map +1 -1
  155. package/dist/tx/status/resolvers/tron.js +18 -2
  156. package/dist/tx/status/resolvers/tron.js.map +1 -1
  157. package/package.json +41 -1
@@ -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;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,MAAM,KAAG,MAiBxD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,EAY9C,CAAA"}
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;AAG1D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,UAAU,CAAA;AA2C9C;;;;;;;;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;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,KAAG,MAU5E,CAAA;AAED,+FAA+F;AAC/F,eAAO,MAAM,+BAA+B,GAAI,yCAK7C,oBAAoB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;CAqC7D,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"}
@@ -1,4 +1,5 @@
1
1
  import { Chain } from '@vultisig/core-chain/Chain';
2
+ import { isValidClassicAddress } from 'ripple-address-codec';
2
3
  /**
3
4
  * Owner-reserve locked by each XRP Ledger object a wallet owns, including every
4
5
  * trust line. Opening a trust line raises the account's required reserve by this
@@ -11,13 +12,32 @@ const standardCurrencyCodeLength = 3;
11
12
  /** Non-standard XRPL currency codes are a 160-bit value, i.e. 40 hex chars. */
12
13
  const hexCurrencyCodeLength = 40;
13
14
  const hexCurrencyCodeRegex = /^[0-9a-fA-F]{40}$/;
15
+ /**
16
+ * Characters XRPL permits inside a 3-character standard currency code. Both
17
+ * letter cases are legal on the ledger, so `usd` is a distinct currency from
18
+ * `USD` rather than a malformed code.
19
+ * @see https://xrpl.org/docs/references/protocol/data-types/currency-formats
20
+ */
21
+ const standardCurrencyCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789<>(){}[]|?!@#$%^&*';
22
+ /**
23
+ * Codes the ledger reserves for native XRP. Compared case-insensitively so a
24
+ * lookalike such as `xrp` cannot be signed as though it were a token.
25
+ */
26
+ const nativeCurrencyCodes = ['XRP', '0'.repeat(40), '0000000000000000000000005852500000000000'];
14
27
  const asciiToHexCurrencyCode = (currency) => {
15
- const bytes = Buffer.from(currency, 'ascii');
28
+ const bytes = [...currency].map(character => {
29
+ const code = character.charCodeAt(0);
30
+ if (code > 127) {
31
+ throw new Error('Unsupported XRP issued-currency code: expected ASCII or a 160-bit hex code');
32
+ }
33
+ return code;
34
+ });
16
35
  if (bytes.length > 20) {
17
36
  throw new Error(`XRPL currency code too long: "${currency}" (max 20 bytes)`);
18
37
  }
19
- return Buffer.concat([bytes, Buffer.alloc(20 - bytes.length)])
20
- .toString('hex')
38
+ return [...bytes, ...Array(20 - bytes.length).fill(0)]
39
+ .map(byte => byte.toString(16).padStart(2, '0'))
40
+ .join('')
21
41
  .toUpperCase();
22
42
  };
23
43
  /**
@@ -68,7 +88,8 @@ export const parseRippleTokenId = (id) => {
68
88
  /**
69
89
  * Formats an issued-currency base-unit amount as an XRPL value string: a plain
70
90
  * decimal (never scientific notation) with trailing-zero fractional digits
71
- * trimmed. XRPL issued amounts allow up to 15 significant digits.
91
+ * trimmed. This formats values for display; use getSignableIssuedCurrencyAmount
92
+ * when the value must be exactly representable on the ledger.
72
93
  */
73
94
  export const formatIssuedCurrencyValue = (amount, decimals) => {
74
95
  const negative = amount < 0n;
@@ -78,9 +99,47 @@ export const formatIssuedCurrencyValue = (amount, decimals) => {
78
99
  const magnitude = fracPart ? `${intPart}.${fracPart}` : intPart;
79
100
  return negative && magnitude !== '0' ? `-${magnitude}` : magnitude;
80
101
  };
102
+ /** Construct an issued amount without letting a signer change its asset or round its value. */
103
+ export const getSignableIssuedCurrencyAmount = ({ currency, issuer, amount, decimals, }) => {
104
+ if ([...currency].some(character => character.charCodeAt(0) > 127)) {
105
+ throw new Error('Unsupported XRP issued-currency code: expected ASCII or a 160-bit hex code');
106
+ }
107
+ const code = toXrplCurrencyCode(currency);
108
+ const standardCode = code.length === standardCurrencyCodeLength &&
109
+ [...code].every(character => standardCurrencyCharacters.includes(character));
110
+ if ((!standardCode && !hexCurrencyCodeRegex.test(code)) || nativeCurrencyCodes.includes(code.toUpperCase())) {
111
+ throw new Error('Unsupported XRP issued-currency code: signing must preserve its exact identity');
112
+ }
113
+ if (!isValidClassicAddress(issuer)) {
114
+ throw new Error('Invalid XRP issued-currency issuer address');
115
+ }
116
+ if (!Number.isInteger(decimals) || decimals < 0 || decimals > 96 || amount < 0n) {
117
+ throw new Error('Invalid XRP issued-currency amount or decimal scale');
118
+ }
119
+ // XRPL uses a 16-digit mantissa and exponent [-96, 80]. Reject rather than
120
+ // silently truncating a quantity that the user already reviewed.
121
+ const digits = amount.toString();
122
+ const significantDigits = digits.replace(/0+$/, '').length;
123
+ const magnitude = digits.length - decimals - 1;
124
+ if (amount !== 0n && (significantDigits > 16 || magnitude < -81 || magnitude > 95)) {
125
+ throw new Error('XRP issued-currency amount is not exactly representable (maximum 16 significant digits)');
126
+ }
127
+ // WalletCore checks the exponent after trimming trailing zeroes, before
128
+ // padding the mantissa to 16 digits. Keep all signers within that supported
129
+ // subset and reject unsupported values before review, not during signing.
130
+ const trimmedExponent = digits.length - significantDigits - decimals;
131
+ if (amount !== 0n && trimmedExponent > 80) {
132
+ throw new Error('XRP issued-currency amount exceeds the supported signer exponent');
133
+ }
134
+ return {
135
+ currency: code,
136
+ issuer,
137
+ value: formatIssuedCurrencyValue(amount, decimals),
138
+ };
139
+ };
81
140
  /**
82
- * XRPL issued currencies carry up to 15 significant decimal digits rather than a
83
- * fixed on-chain decimal count. We model them internally with this many decimals.
141
+ * XRPL issued currencies carry up to 16 significant decimal digits rather than a
142
+ * fixed on-chain decimal count. Our fixed-point balance model uses 15 decimals.
84
143
  */
85
144
  export const rippleIssuedCurrencyDecimals = 15;
86
145
  /**
@@ -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,22 @@
1
+ /** The `account_lines` fields that say which asset a trust line is for. */
2
+ export type RippleTrustLineAsset = {
3
+ /** The line's counterparty — the issuer, from the holder's perspective. */
4
+ account: string;
5
+ currency: string;
6
+ };
7
+ type FindRippleTrustLineInput<T extends RippleTrustLineAsset> = {
8
+ lines: T[];
9
+ currency: string;
10
+ issuer: string;
11
+ };
12
+ /**
13
+ * The trust line among `lines` that holds `(currency, issuer)`, or `undefined`
14
+ * when the account has none.
15
+ *
16
+ * Currency codes are compared normalised, so a node spelling a non-standard code
17
+ * in lowercase hex still matches a token id that holds it uppercased. Issuer
18
+ * addresses are base58 and compared case-SENSITIVELY.
19
+ */
20
+ export declare const findRippleTrustLine: <T extends RippleTrustLineAsset>({ lines, currency, issuer, }: FindRippleTrustLineInput<T>) => T | undefined;
21
+ export {};
22
+ //# sourceMappingURL=trustLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trustLine.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ripple/trustLine.ts"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB,GAAG;IACjC,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,KAAK,wBAAwB,CAAC,CAAC,SAAS,oBAAoB,IAAI;IAC9D,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,oBAAoB,EAAE,8BAIjE,wBAAwB,CAAC,CAAC,CAAC,KAAG,CAAC,GAAG,SAIpC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { toXrplCurrencyCode } from '@vultisig/core-chain/chains/ripple/issuedCurrency';
2
+ /**
3
+ * The trust line among `lines` that holds `(currency, issuer)`, or `undefined`
4
+ * when the account has none.
5
+ *
6
+ * Currency codes are compared normalised, so a node spelling a non-standard code
7
+ * in lowercase hex still matches a token id that holds it uppercased. Issuer
8
+ * addresses are base58 and compared case-SENSITIVELY.
9
+ */
10
+ export const findRippleTrustLine = ({ lines, currency, issuer, }) => {
11
+ const code = toXrplCurrencyCode(currency);
12
+ return lines.find(line => line.account === issuer && toXrplCurrencyCode(line.currency) === code);
13
+ };
14
+ //# sourceMappingURL=trustLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trustLine.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ripple/trustLine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAA;AAetF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAiC,EAClE,KAAK,EACL,QAAQ,EACR,MAAM,GACsB,EAAiB,EAAE;IAC/C,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;IAEzC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAA;AAClG,CAAC,CAAA"}
@@ -12,4 +12,36 @@ export declare const tonAddressToRaw: (userFriendlyAddress: string) => string;
12
12
  * already in user-friendly form are returned re-encoded as bounceable.
13
13
  */
14
14
  export declare const tonAddressToBounceable: (address: string) => string;
15
+ /**
16
+ * What a TON destination address declares about bouncing. `unspecified` covers the
17
+ * raw `0:hex` spelling and anything unparseable — those carry no tag byte at all,
18
+ * which is exactly the case a leading-character check cannot express.
19
+ */
20
+ export type TonAddressBounceability = 'bounceable' | 'nonBounceable' | 'unspecified';
21
+ /**
22
+ * Reads the bounce tag out of a user-friendly TON address instead of inferring it
23
+ * from the leading `E`/`U`. The tag lives in the first byte of the base64 payload
24
+ * (`0x11` bounceable / `0x51` not, `| 0x80` on testnet) and is checksum-protected,
25
+ * so a raw or corrupted address reports `unspecified` rather than a flag it never
26
+ * declared — leaving the caller to pick the safe default for its own context.
27
+ */
28
+ export declare const getTonAddressBounceability: (address: string) => TonAddressBounceability;
29
+ /**
30
+ * Whether two TON addresses name the same account.
31
+ *
32
+ * One account has several textual spellings — raw `workchain:hex`, bounceable
33
+ * `EQ…`, non-bounceable `UQ…`, and the base64 / base64url variants of both —
34
+ * and only the flag byte and checksum differ between `EQ` and `UQ`. String
35
+ * equality therefore reports differences that do not exist, which matters
36
+ * wherever two independently sourced addresses are cross-checked before money
37
+ * moves. Input that does not parse as a TON address falls back to exact
38
+ * comparison rather than being reported as a match.
39
+ */
40
+ export declare const areEqualTonAddresses: (left: string, right: string) => boolean;
41
+ /**
42
+ * Lower-cased raw (`workchain:hex`) form of a raw or user-friendly TON address.
43
+ * Toncenter answers in upper-case hex and ton-assets lists lower-case hex, so
44
+ * every lookup keyed by a jetton master address must go through this first.
45
+ */
46
+ export declare const tonAddressToRawKey: (address: string) => string;
15
47
  //# sourceMappingURL=address.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/address.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,qBAAqB,MAAM,KAAG,MAM7D,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,MAIxD,CAAA"}
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/address.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,qBAAqB,MAAM,KAAG,MAM7D,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,MAIxD,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,eAAe,GAAG,aAAa,CAAA;AAEpF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,SAAS,MAAM,KAAG,uBAQ5D,CAAA;AAUD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,OAKlE,CAAA;AACD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,MACuB,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { Address } from '@ton/core';
2
+ import { attempt } from '@vultisig/lib-utils/attempt';
2
3
  import { fromBase64 } from '@vultisig/lib-utils/fromBase64';
3
4
  /** Converts base64url encoding to standard base64 so `Buffer.from` can decode it. */
4
5
  const fromBase64Url = (value) => {
@@ -27,4 +28,48 @@ export const tonAddressToBounceable = (address) => {
27
28
  const parsed = address.includes(':') ? Address.parseRaw(address) : Address.parse(address);
28
29
  return parsed.toString({ bounceable: true, testOnly: false, urlSafe: true });
29
30
  };
31
+ /**
32
+ * Reads the bounce tag out of a user-friendly TON address instead of inferring it
33
+ * from the leading `E`/`U`. The tag lives in the first byte of the base64 payload
34
+ * (`0x11` bounceable / `0x51` not, `| 0x80` on testnet) and is checksum-protected,
35
+ * so a raw or corrupted address reports `unspecified` rather than a flag it never
36
+ * declared — leaving the caller to pick the safe default for its own context.
37
+ */
38
+ export const getTonAddressBounceability = (address) => {
39
+ const parsed = attempt(() => Address.parseFriendly(address));
40
+ if ('error' in parsed) {
41
+ return 'unspecified';
42
+ }
43
+ return parsed.data.isBounceable ? 'bounceable' : 'nonBounceable';
44
+ };
45
+ const parseTonAddress = (address) => {
46
+ try {
47
+ return Address.parse(address.trim());
48
+ }
49
+ catch {
50
+ return undefined;
51
+ }
52
+ };
53
+ /**
54
+ * Whether two TON addresses name the same account.
55
+ *
56
+ * One account has several textual spellings — raw `workchain:hex`, bounceable
57
+ * `EQ…`, non-bounceable `UQ…`, and the base64 / base64url variants of both —
58
+ * and only the flag byte and checksum differ between `EQ` and `UQ`. String
59
+ * equality therefore reports differences that do not exist, which matters
60
+ * wherever two independently sourced addresses are cross-checked before money
61
+ * moves. Input that does not parse as a TON address falls back to exact
62
+ * comparison rather than being reported as a match.
63
+ */
64
+ export const areEqualTonAddresses = (left, right) => {
65
+ const parsedLeft = parseTonAddress(left);
66
+ const parsedRight = parseTonAddress(right);
67
+ return parsedLeft && parsedRight ? parsedLeft.equals(parsedRight) : left.trim() === right.trim();
68
+ };
69
+ /**
70
+ * Lower-cased raw (`workchain:hex`) form of a raw or user-friendly TON address.
71
+ * Toncenter answers in upper-case hex and ton-assets lists lower-case hex, so
72
+ * every lookup keyed by a jetton master address must go through this first.
73
+ */
74
+ export const tonAddressToRawKey = (address) => (address.includes(':') ? address : tonAddressToRaw(address)).toLowerCase();
30
75
  //# sourceMappingURL=address.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"address.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAE3D,qFAAqF;AACrF,MAAM,aAAa,GAAG,CAAC,KAAa,EAAU,EAAE;IAC9C,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAClE,OAAO,UAAU,CAAC,cAAc,CAAC,CAAA;AACnC,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,mBAA2B,EAAU,EAAE;IACrE,MAAM,OAAO,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEpD,OAAO,GAAG,SAAS,IAAI,IAAI,EAAE,CAAA;AAC/B,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAU,EAAE;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEzF,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9E,CAAC,CAAA"}
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/address.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,20 @@ export declare const getJettonWalletAddress: (input: GetJettonWalletInput) => Pr
7
7
  /** Fetches the balance of a specific jetton for a given owner address. */
8
8
  export declare const getJettonBalance: (input: GetJettonWalletInput) => Promise<bigint>;
9
9
  export declare const getTonWalletState: (address: string) => Promise<string>;
10
+ /**
11
+ * Display metadata Toncenter holds for a jetton master, without any of the
12
+ * fields being guaranteed: an unindexed or broken jetton can lack all of them.
13
+ */
14
+ export type JettonMasterMetadata = {
15
+ /** Raw `workchain:hex` address, lower-cased (see `tonAddressToRawKey`). */
16
+ address: string;
17
+ symbol?: string;
18
+ name?: string;
19
+ decimals?: number;
20
+ logo?: string;
21
+ /** `true` when Toncenter's indexer has flagged the jetton as a scam. */
22
+ isFlaggedScam?: boolean;
23
+ };
10
24
  export type JettonMasterInfo = {
11
25
  ticker: string;
12
26
  decimals: number;
@@ -16,7 +30,42 @@ export type JettonMasterInfo = {
16
30
  * Fetches jetton master metadata (ticker, decimals, logo) from toncenter v3.
17
31
  * Prefers Toncenter's validated indexer entry (`token_info` with `valid: true`),
18
32
  * falling back to the on-chain TEP-64 `jetton_content` stored in the master.
33
+ * Throws when the jetton is unknown or has no symbol; decimals default to 9.
19
34
  */
20
35
  export declare const getJettonMasterInfo: (jettonMasterAddress: string) => Promise<JettonMasterInfo>;
36
+ /**
37
+ * Fetches metadata for many jetton masters at once, keyed by lower-cased raw
38
+ * address. Masters Toncenter does not know are simply absent from the result;
39
+ * nothing throws for a missing symbol, unlike `getJettonMasterInfo`.
40
+ */
41
+ export declare const getJettonMastersMetadata: (jettonMasterAddresses: string[]) => Promise<Record<string, JettonMasterMetadata>>;
42
+ export type OwnerJettonWallet = {
43
+ /** Jetton master address as a lower-cased raw key. */
44
+ jettonMasterAddress: string;
45
+ balance: bigint;
46
+ };
47
+ export type OwnerJettonWallets = {
48
+ /** One entry per jetton held, deduplicated by master — see `getOwnerJettonWallets`. */
49
+ wallets: OwnerJettonWallet[];
50
+ /** Indexer metadata for the masters behind `wallets`, keyed like `jettonMasterAddress`. */
51
+ masters: Record<string, JettonMasterMetadata>;
52
+ /** User-friendly spellings Toncenter returned for master addresses, keyed like `jettonMasterAddress`. */
53
+ userFriendlyAddresses: Record<string, string>;
54
+ };
55
+ /**
56
+ * Lists every jetton the owner holds a non-zero balance of, with the master
57
+ * metadata Toncenter embeds in the same response, so discovery needs no
58
+ * follow-up call per jetton. Pages through the proxy and keeps only wallets
59
+ * whose `owner` is the requested address (the proxy has been seen to return
60
+ * unfiltered lists).
61
+ *
62
+ * Each jetton appears once. An owner holds exactly one wallet per master, so a
63
+ * master seen twice is the same holding served again — which is what a proxy
64
+ * that ignores `offset` does, replaying page one until the page cap and turning
65
+ * one balance into twenty. Paging stops as soon as a page adds nothing new,
66
+ * because a page of holdings already recorded is the end of the list however the
67
+ * proxy chose to express it.
68
+ */
69
+ export declare const getOwnerJettonWallets: (ownerAddress: string) => Promise<OwnerJettonWallets>;
21
70
  export {};
22
71
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/api.ts"],"names":[],"mappings":"AAwBA,KAAK,oBAAoB,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;CAC5B,CAAA;AAiCD,4FAA4F;AAC5F,eAAO,MAAM,sBAAsB,GAAU,OAAO,oBAAoB,KAAG,OAAO,CAAC,MAAM,CAOxF,CAAA;AAED,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,GAAU,OAAO,oBAAoB,KAAG,OAAO,CAAC,MAAM,CAIlF,CAAA;AAOD,eAAO,MAAM,iBAAiB,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAKvE,CAAA;AA4CD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAU,qBAAqB,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAsC/F,CAAA"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/api.ts"],"names":[],"mappings":"AAqDA,KAAK,oBAAoB,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;CAC5B,CAAA;AAiCD,4FAA4F;AAC5F,eAAO,MAAM,sBAAsB,GAAU,OAAO,oBAAoB,KAAG,OAAO,CAAC,MAAM,CAOxF,CAAA;AAED,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,GAAU,OAAO,oBAAoB,KAAG,OAAO,CAAC,MAAM,CAIlF,CAAA;AAOD,eAAO,MAAM,iBAAiB,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAKvE,CAAA;AAuBD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AA6DD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAU,qBAAqB,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAoB/F,CAAA;AAMD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,uBAAuB,MAAM,EAAE,KAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAmB9C,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,sDAAsD;IACtD,mBAAmB,EAAE,MAAM,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,uFAAuF;IACvF,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAC7C,yGAAyG;IACzG,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9C,CAAA;AASD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAU,cAAc,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAwC5F,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { rootApiUrl } from '@vultisig/core-config';
2
+ import { toBatches } from '@vultisig/lib-utils/array/toBatches';
2
3
  import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
3
- import { tonAddressToRaw } from './address.js';
4
+ import { tonAddressToRawKey } from './address.js';
4
5
  const tonApiUrl = `${rootApiUrl}/ton`;
5
6
  const matchesRawAddress = (value, expected) => value.toLowerCase() === expected.toLowerCase();
6
7
  /**
@@ -13,8 +14,8 @@ const matchesRawAddress = (value, expected) => value.toLowerCase() === expected.
13
14
  * stranger's balance (e.g. a whale's 200M USDT instead of the user's 0).
14
15
  */
15
16
  const queryOwnerJettonWallet = async ({ ownerAddress, jettonMasterAddress, }) => {
16
- const rawOwner = tonAddressToRaw(ownerAddress);
17
- const rawMaster = tonAddressToRaw(jettonMasterAddress);
17
+ const rawOwner = tonAddressToRawKey(ownerAddress);
18
+ const rawMaster = tonAddressToRawKey(jettonMasterAddress);
18
19
  const url = `${tonApiUrl}/v3/jetton/wallets?owner_address=${rawOwner}&jetton_address=${rawMaster}`;
19
20
  const response = await queryUrl(url);
20
21
  const wallet = response.jetton_wallets.find(({ owner, jetton }) => matchesRawAddress(owner, rawOwner) && matchesRawAddress(jetton, rawMaster));
@@ -38,10 +39,50 @@ export const getTonWalletState = async (address) => {
38
39
  const response = await queryUrl(url);
39
40
  return response.status;
40
41
  };
42
+ const nonEmpty = (value) => {
43
+ const trimmed = value?.trim();
44
+ return trimmed ? trimmed : undefined;
45
+ };
46
+ const parseDecimals = (value) => {
47
+ if (value === undefined)
48
+ return undefined;
49
+ const parsed = parseInt(value, 10);
50
+ return Number.isFinite(parsed) ? parsed : undefined;
51
+ };
52
+ /**
53
+ * Picks the indexer's validated `jetton_masters` entry for an address, if the
54
+ * response carries one. Wallet listings also embed entries of type
55
+ * `jetton_wallets` under the wallet addresses, which are not what we want.
56
+ */
57
+ const getIndexedMasterInfo = (metadata, address) => metadata?.[address]?.token_info?.find(entry => entry.valid === true && (entry.type === undefined || entry.type === 'jetton_masters'));
58
+ /**
59
+ * Merges Toncenter's validated indexer entry with the on-chain TEP-64 content,
60
+ * preferring the indexer. Prefers Toncenter's imgproxy URLs for the logo: the
61
+ * original `image` URL often serves with `Cross-Origin-Resource-Policy:
62
+ * same-origin`, which browsers refuse to embed cross-origin, while the
63
+ * `_image_*` variants are normalized PNGs that load reliably in extension and
64
+ * desktop pages.
65
+ */
66
+ const parseJettonMasterMetadata = ({ address, indexed, content, }) => {
67
+ const logo = nonEmpty(indexed?.extra?._image_medium) ??
68
+ nonEmpty(indexed?.extra?._image_small) ??
69
+ nonEmpty(indexed?.extra?._image_big) ??
70
+ nonEmpty(indexed?.image) ??
71
+ nonEmpty(content?.image);
72
+ return {
73
+ address: tonAddressToRawKey(address),
74
+ symbol: nonEmpty(indexed?.symbol) ?? nonEmpty(content?.symbol),
75
+ name: nonEmpty(indexed?.name) ?? nonEmpty(content?.name),
76
+ decimals: parseDecimals(indexed?.extra?.decimals ?? content?.decimals),
77
+ logo,
78
+ ...(indexed?.is_scam === undefined ? {} : { isFlaggedScam: indexed.is_scam }),
79
+ };
80
+ };
41
81
  /**
42
82
  * Fetches jetton master metadata (ticker, decimals, logo) from toncenter v3.
43
83
  * Prefers Toncenter's validated indexer entry (`token_info` with `valid: true`),
44
84
  * falling back to the on-chain TEP-64 `jetton_content` stored in the master.
85
+ * Throws when the jetton is unknown or has no symbol; decimals default to 9.
45
86
  */
46
87
  export const getJettonMasterInfo = async (jettonMasterAddress) => {
47
88
  const url = `${tonApiUrl}/v3/jetton/masters?address=${encodeURIComponent(jettonMasterAddress)}&limit=1`;
@@ -50,28 +91,94 @@ export const getJettonMasterInfo = async (jettonMasterAddress) => {
50
91
  if (!master) {
51
92
  throw new Error(`No jetton master found for ${jettonMasterAddress}`);
52
93
  }
53
- const nonEmpty = (value) => {
54
- const trimmed = value?.trim();
55
- return trimmed ? trimmed : undefined;
56
- };
57
- const indexed = response.metadata?.[master.address]?.token_info?.find(entry => entry.valid === true);
58
- const content = master.jetton_content;
59
- const ticker = nonEmpty(indexed?.symbol) ?? nonEmpty(content?.symbol);
60
- if (!ticker) {
94
+ const { symbol, decimals, logo } = parseJettonMasterMetadata({
95
+ address: master.address,
96
+ indexed: getIndexedMasterInfo(response.metadata, master.address),
97
+ content: master.jetton_content,
98
+ });
99
+ if (!symbol) {
61
100
  throw new Error(`Jetton master ${jettonMasterAddress} has no symbol`);
62
101
  }
63
- const decimalsRaw = indexed?.extra?.decimals ?? content?.decimals;
64
- const parsedDecimals = decimalsRaw !== undefined ? parseInt(decimalsRaw, 10) : NaN;
65
- const decimals = Number.isFinite(parsedDecimals) ? parsedDecimals : 9;
66
- // Prefer Toncenter's imgproxy URLs: the original `image` URL often serves
67
- // with `Cross-Origin-Resource-Policy: same-origin`, which browsers refuse
68
- // to embed cross-origin. The `_image_*` variants are normalized PNGs from
69
- // `imgproxy.toncenter.com` and load reliably in extension/desktop pages.
70
- const logo = nonEmpty(indexed?.extra?._image_medium) ??
71
- nonEmpty(indexed?.extra?._image_small) ??
72
- nonEmpty(indexed?.extra?._image_big) ??
73
- nonEmpty(indexed?.image) ??
74
- nonEmpty(content?.image);
75
- return { ticker, decimals, logo };
102
+ return { ticker: symbol, decimals: decimals ?? 9, logo };
103
+ };
104
+ // Toncenter accepts a comma-separated address list; each raw address is ~67
105
+ // chars, so 50 keeps the query string comfortably under gateway URI limits.
106
+ const jettonMastersPerRequest = 50;
107
+ /**
108
+ * Fetches metadata for many jetton masters at once, keyed by lower-cased raw
109
+ * address. Masters Toncenter does not know are simply absent from the result;
110
+ * nothing throws for a missing symbol, unlike `getJettonMasterInfo`.
111
+ */
112
+ export const getJettonMastersMetadata = async (jettonMasterAddresses) => {
113
+ const rawAddresses = [...new Set(jettonMasterAddresses.map(tonAddressToRawKey))];
114
+ const result = {};
115
+ for (const batch of toBatches(rawAddresses, jettonMastersPerRequest)) {
116
+ const url = `${tonApiUrl}/v3/jetton/masters?address=${batch.join(',')}&limit=${batch.length}`;
117
+ const response = await queryUrl(url);
118
+ for (const master of response.jetton_masters) {
119
+ const metadata = parseJettonMasterMetadata({
120
+ address: master.address,
121
+ indexed: getIndexedMasterInfo(response.metadata, master.address),
122
+ content: master.jetton_content,
123
+ });
124
+ result[metadata.address] = metadata;
125
+ }
126
+ }
127
+ return result;
128
+ };
129
+ const ownerJettonWalletsPageSize = 100;
130
+ // 2000 distinct jettons is far beyond any real wallet. The cap is the last resort
131
+ // for a proxy that keeps serving pages forever; the duplicate check below normally
132
+ // stops long before it.
133
+ const ownerJettonWalletsMaxPages = 20;
134
+ /**
135
+ * Lists every jetton the owner holds a non-zero balance of, with the master
136
+ * metadata Toncenter embeds in the same response, so discovery needs no
137
+ * follow-up call per jetton. Pages through the proxy and keeps only wallets
138
+ * whose `owner` is the requested address (the proxy has been seen to return
139
+ * unfiltered lists).
140
+ *
141
+ * Each jetton appears once. An owner holds exactly one wallet per master, so a
142
+ * master seen twice is the same holding served again — which is what a proxy
143
+ * that ignores `offset` does, replaying page one until the page cap and turning
144
+ * one balance into twenty. Paging stops as soon as a page adds nothing new,
145
+ * because a page of holdings already recorded is the end of the list however the
146
+ * proxy chose to express it.
147
+ */
148
+ export const getOwnerJettonWallets = async (ownerAddress) => {
149
+ // Accept the owner in either spelling: `tonAddressToRaw` alone would base64-decode
150
+ // a raw `0:hex` address into garbage and the proxy would answer with no wallets.
151
+ const rawOwner = tonAddressToRawKey(ownerAddress);
152
+ const wallets = [];
153
+ const seenMasters = new Set();
154
+ const masters = {};
155
+ const userFriendlyAddresses = {};
156
+ for (let page = 0; page < ownerJettonWalletsMaxPages; page++) {
157
+ const offset = page * ownerJettonWalletsPageSize;
158
+ const url = `${tonApiUrl}/v3/jetton/wallets?owner_address=${rawOwner}&exclude_zero_balance=true&limit=${ownerJettonWalletsPageSize}&offset=${offset}`;
159
+ const response = await queryUrl(url);
160
+ const walletsBeforePage = seenMasters.size;
161
+ for (const wallet of response.jetton_wallets) {
162
+ if (!matchesRawAddress(wallet.owner, rawOwner))
163
+ continue;
164
+ const jettonMasterAddress = tonAddressToRawKey(wallet.jetton);
165
+ if (seenMasters.has(jettonMasterAddress))
166
+ continue;
167
+ seenMasters.add(jettonMasterAddress);
168
+ wallets.push({ jettonMasterAddress, balance: BigInt(wallet.balance || '0') });
169
+ const indexed = getIndexedMasterInfo(response.metadata, wallet.jetton);
170
+ if (indexed) {
171
+ masters[jettonMasterAddress] = parseJettonMasterMetadata({ address: wallet.jetton, indexed });
172
+ }
173
+ const userFriendly = response.address_book?.[wallet.jetton]?.user_friendly;
174
+ if (userFriendly) {
175
+ userFriendlyAddresses[jettonMasterAddress] = userFriendly;
176
+ }
177
+ }
178
+ const isLastPage = response.jetton_wallets.length < ownerJettonWalletsPageSize;
179
+ if (isLastPage || seenMasters.size === walletsBeforePage)
180
+ break;
181
+ }
182
+ return { wallets, masters, userFriendlyAddresses };
76
183
  };
77
184
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The longest UTF-8 comment a native TON transfer can carry.
3
+ *
4
+ * The comment is the message body's own cell, so everything after the opcode is
5
+ * available: (1023 - 32) / 8.
6
+ */
7
+ export declare const tonNativeCommentMaxBytes: number;
8
+ export type TonJettonCommentContext = {
9
+ /** Jetton amount in minimal units — the same value the transfer sends. */
10
+ amount: bigint;
11
+ /** Whether the recipient is initialized; decides the forward amount (1 vs 0). */
12
+ isActiveDestination: boolean;
13
+ };
14
+ /**
15
+ * The longest UTF-8 comment a jetton transfer can carry *for this amount*.
16
+ *
17
+ * A jetton comment is not a body of its own: it rides inline in the transfer
18
+ * body's `forward_payload`, sharing one 1023-bit cell with the opcode, query id,
19
+ * amount, both addresses and the forward amount. WalletCore emits only that
20
+ * inline form — it never spills the payload into a referenced cell — so the cap
21
+ * is whatever those fields leave behind, roughly 34–39 bytes. It SHRINKS as the
22
+ * amount grows, because `VarUInteger 16` widens a byte at a time. A fixed byte
23
+ * count is therefore always wrong for jettons.
24
+ *
25
+ * The amount-dependent widths are measured by encoding them rather than
26
+ * predicted, so the answer cannot drift from the encoder it describes.
27
+ */
28
+ export declare const getTonJettonCommentMaxBytes: ({ amount, isActiveDestination }: TonJettonCommentContext) => number;
29
+ export type TonCommentInput = {
30
+ memo: string;
31
+ /** Jetton transfer context. Omit for a native TON transfer. */
32
+ jetton?: TonJettonCommentContext;
33
+ };
34
+ /**
35
+ * The longest UTF-8 comment this transfer can carry, in bytes — a native cell's
36
+ * 123, or the amount-dependent inline capacity of a jetton transfer.
37
+ *
38
+ * Exposed so a send form can cap or count down against the real limit instead
39
+ * of discovering it at keysign.
40
+ */
41
+ export declare const getTonCommentMaxBytes: ({ jetton }: Pick<TonCommentInput, "jetton">) => number;
42
+ /**
43
+ * Rejects a TON comment that will not fit the cell it is destined for.
44
+ *
45
+ * Memos are load-bearing on TON — an exchange deposit without the right one
46
+ * loses the funds — so this is the single place that decides whether a comment
47
+ * is sendable. Run it before the user commits, not at keysign, where an
48
+ * oversized jetton comment surfaces as a bare WalletCore "Internal error".
49
+ */
50
+ export declare const validateTonComment: ({ memo, jetton }: TonCommentInput) => void;
51
+ //# sourceMappingURL=comment.d.ts.map