@vultisig/core-chain 5.0.0 → 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 (50) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/chains/ripple/issuedCurrency.d.ts.map +1 -1
  3. package/dist/chains/ripple/issuedCurrency.js +15 -4
  4. package/dist/chains/ripple/issuedCurrency.js.map +1 -1
  5. package/dist/chains/ripple/trustLine.d.ts +22 -0
  6. package/dist/chains/ripple/trustLine.d.ts.map +1 -0
  7. package/dist/chains/ripple/trustLine.js +14 -0
  8. package/dist/chains/ripple/trustLine.js.map +1 -0
  9. package/dist/chains/ton/address.d.ts +18 -0
  10. package/dist/chains/ton/address.d.ts.map +1 -1
  11. package/dist/chains/ton/address.js +30 -0
  12. package/dist/chains/ton/address.js.map +1 -1
  13. package/dist/chains/ton/api.d.ts +49 -0
  14. package/dist/chains/ton/api.d.ts.map +1 -1
  15. package/dist/chains/ton/api.js +131 -24
  16. package/dist/chains/ton/api.js.map +1 -1
  17. package/dist/chains/ton/jetton/symbol.d.ts +9 -0
  18. package/dist/chains/ton/jetton/symbol.d.ts.map +1 -0
  19. package/dist/chains/ton/jetton/symbol.js +61 -0
  20. package/dist/chains/ton/jetton/symbol.js.map +1 -0
  21. package/dist/chains/ton/jetton/verification.d.ts +35 -0
  22. package/dist/chains/ton/jetton/verification.d.ts.map +1 -0
  23. package/dist/chains/ton/jetton/verification.js +45 -0
  24. package/dist/chains/ton/jetton/verification.js.map +1 -0
  25. package/dist/chains/ton/jetton/verifiedRegistry.d.ts +43 -0
  26. package/dist/chains/ton/jetton/verifiedRegistry.d.ts.map +1 -0
  27. package/dist/chains/ton/jetton/verifiedRegistry.js +94 -0
  28. package/dist/chains/ton/jetton/verifiedRegistry.js.map +1 -0
  29. package/dist/coin/balance/resolvers/ripple.d.ts.map +1 -1
  30. package/dist/coin/balance/resolvers/ripple.js +3 -2
  31. package/dist/coin/balance/resolvers/ripple.js.map +1 -1
  32. package/dist/coin/find/CoinFinderChainKind.d.ts +1 -1
  33. package/dist/coin/find/CoinFinderChainKind.d.ts.map +1 -1
  34. package/dist/coin/find/CoinFinderChainKind.js +1 -1
  35. package/dist/coin/find/CoinFinderChainKind.js.map +1 -1
  36. package/dist/coin/find/index.d.ts.map +1 -1
  37. package/dist/coin/find/index.js +2 -0
  38. package/dist/coin/find/index.js.map +1 -1
  39. package/dist/coin/find/resolvers/ton.d.ts +15 -0
  40. package/dist/coin/find/resolvers/ton.d.ts.map +1 -0
  41. package/dist/coin/find/resolvers/ton.js +61 -0
  42. package/dist/coin/find/resolvers/ton.js.map +1 -0
  43. package/dist/coin/tokenVerification.d.ts +13 -0
  44. package/dist/coin/tokenVerification.d.ts.map +1 -0
  45. package/dist/coin/tokenVerification.js +12 -0
  46. package/dist/coin/tokenVerification.js.map +1 -0
  47. package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
  48. package/dist/swap/general/swapkit/api/getSwapKitQuote.js +89 -5
  49. package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
  50. package/package.json +31 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @vultisig/core-chain
2
2
 
3
+ ## 5.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#2305](https://github.com/vultisig/vultisig-sdk/pull/2305) [`20de22f`](https://github.com/vultisig/vultisig-sdk/commit/20de22f49c244ffc065011291754f89ef0d6e61a) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - feat(ton): jetton auto-discovery with verified / unverified / scam classification
8
+
9
+ TON wallets get carpet-bombed with counterfeit jettons — fake USDT above all — and until now the SDK could neither find the jettons an address holds nor say which of them to trust: discovery covered EVM, Solana, Cosmos, Cardano and Ripple, and TON shipped nine curated jettons plus manual add. A wallet with no labels cannot protect a user from the most common TON scam.
10
+
11
+ `findCoins` now supports `Chain.Ton` (`coinFinderChainKinds` gains `'ton'`). `findTonCoins` lists every jetton with a non-zero balance through the Toncenter proxy in one paged call — the indexer's symbol, name, decimals and logo ride along, so there is no follow-up call per jetton — and returns only jettons that pass verification. Curated metadata wins for jettons we ship ourselves.
12
+
13
+ Verification lives in `@vultisig/core-chain/chains/ton/jetton/verification`. The registry of verified jettons (`chains/ton/jetton/verifiedRegistry`) merges our curated TON tokens with Tonkeeper's community-reviewed `ton-assets` whitelist, fetched once an hour and degrading to the curated list alone when unreachable. `resolveTonJettonVerification` is pure: a listed address is `verified`; an unlisted jetton is `scam` when the indexer flags it or when its symbol or name collapses onto a verified jetton's — `normalizeJettonSymbol` folds `USD₮`, Cyrillic `UЅDT`, `$USĐ₮` and full-width forms onto `USDT` — and `unverified` otherwise. `getTonJettonVerification({ id, ticker })` is the one-call form for token rows and approval cards; it judges the master by what it claims on chain, falling back to the local ticker offline. The tiers are the chain-agnostic `TokenVerification` type in `@vultisig/core-chain/coin/tokenVerification`.
14
+
15
+ `chains/ton/api` gains `getOwnerJettonWallets` (paged, owner-filtered, one entry per jetton, with embedded master metadata) and `getJettonMastersMetadata` (batched, lenient master lookup keyed by lower-cased raw address), and `chains/ton/address` gains `tonAddressToRawKey`. `vault.discoverTokens(Chain.Ton)` and `Vultisig.discoverTokens` work for TON through the same path.
16
+
17
+ ### Patch Changes
18
+
19
+ - [#2323](https://github.com/vultisig/vultisig-sdk/pull/2323) [`8a50970`](https://github.com/vultisig/vultisig-sdk/commit/8a50970438de64cdbeb281cf73925026e3ce3cf7) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Refuse XRPL issued-currency Payments the ledger would reject — a destination holding no trust line for the token, and an issuer that charges a transfer fee the payload cannot yet cover with a SendMax — instead of burning the fee on-chain. Accept the lowercase standard currency codes XRPL permits, report bad amounts and unusable destinations as domain errors, and pin both encoders against a shared issued-currency signing vector.
20
+
21
+ - [#2310](https://github.com/vultisig/vultisig-sdk/pull/2310) [`af6c643`](https://github.com/vultisig/vultisig-sdk/commit/af6c643e9afa39cb0b4432a01cec40e4de4d8ecc) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - fix(ton): let a dApp deadline tighten the signed expiry
22
+
23
+ `getTonChainSpecific` always signed `expireAt = now + 600`, so the `valid_until` a TonConnect `sendTransaction` carries never reached the wallet message: a request with a 60-second window was signed with a ten-minute one, and a broadcast landing after the dApp's window could execute on chain while the dApp already treated it as expired and retried.
24
+
25
+ `GetChainSpecificInput` now takes an optional `validUntil` (unix seconds) for `tonSpecific`. The signed `expireAt` is `min(now + 600, validUntil)` — the wallet's own window remains the ceiling — and a deadline already in the past fails the build instead of signing a transaction the network would reject. Callers that pass nothing keep the previous behaviour; co-signers read `expireAt` from the payload, so only what the initiator writes changes.
26
+
27
+ The expiry is computed last, after the seqno, bounceability and jetton-metadata lookups: each is a network round trip, so a deadline still ahead when the build starts can be behind by the time it finishes, and the wallet's own ten-minute window now starts when the payload is finished rather than being partly spent on those lookups.
28
+
29
+ - [#2296](https://github.com/vultisig/vultisig-sdk/pull/2296) [`34f0faa`](https://github.com/vultisig/vultisig-sdk/commit/34f0faa7208ad594b8d18a3a2806c0f7867f2c85) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - fix(ton): cross-check SwapKit's `tx[]` transfer against the deposit address and amount it also returns
30
+
31
+ A SwapKit `/v3/swap` response states the deposit destination in up to three independent fields — `targetAddress`, `depositAddress`, and the `tx[]` transfer array — and its size in two (`depositAmount`, `tx[0].amount`). The transfer builder took the first field that was present and never looked at the rest, so a response whose halves diverged (provider bug, API change, tampered payload) signed whichever field happened to win the precedence order while the others named a different recipient or a different size. Nothing downstream could tell.
32
+
33
+ `buildTransferTx` now refuses a response that disagrees with itself, on either the destination or the amount, instead of resolving the ambiguity by precedence. It also rejects a multi-entry `tx[]` rather than silently signing only the first transfer and under-funding the swap.
34
+
35
+ Destinations are compared per chain: TON spells one account as `EQ…`, `UQ…` or raw `workchain:hex`, so the new `areEqualTonAddresses` helper compares parsed accounts there, while every other transfer chain stays byte-for-byte (base58 is case-sensitive — normalizing case away would let two different addresses pass as one).
36
+
37
+ The agreed TON destination is re-spelled in its bounceable (`EQ…`) form whichever field it came from. The agreement check treats `UQ…`, raw and `EQ…` spellings of one account as equal — correctly — but the signer reads the bounce flag off the spelling, so a route that won precedence with a `UQ…` or raw spelling would have sent the deposit non-bounceable, where a rejecting contract absorbs it instead of refunding. A destination that is not a TON address at all is refused.
38
+
3
39
  ## 5.0.0
4
40
 
5
41
  ### Major Changes
@@ -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;AAG1D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,UAAU,CAAA;AA6B9C;;;;;;;;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
+ {"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"}
@@ -12,6 +12,18 @@ const standardCurrencyCodeLength = 3;
12
12
  /** Non-standard XRPL currency codes are a 160-bit value, i.e. 40 hex chars. */
13
13
  const hexCurrencyCodeLength = 40;
14
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'];
15
27
  const asciiToHexCurrencyCode = (currency) => {
16
28
  const bytes = [...currency].map(character => {
17
29
  const code = character.charCodeAt(0);
@@ -93,10 +105,9 @@ export const getSignableIssuedCurrencyAmount = ({ currency, issuer, amount, deci
93
105
  throw new Error('Unsupported XRP issued-currency code: expected ASCII or a 160-bit hex code');
94
106
  }
95
107
  const code = toXrplCurrencyCode(currency);
96
- const standardCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789<>(){}[]|?!@#$%^&*';
97
- const standardCode = code.length === 3 && [...code].every(character => standardCharacters.includes(character));
98
- const nativeCodes = ['XRP', '0'.repeat(40), '0000000000000000000000005852500000000000'];
99
- if ((!standardCode && !hexCurrencyCodeRegex.test(code)) || nativeCodes.includes(code)) {
108
+ const standardCode = code.length === standardCurrencyCodeLength &&
109
+ [...code].every(character => standardCurrencyCharacters.includes(character));
110
+ if ((!standardCode && !hexCurrencyCodeRegex.test(code)) || nativeCurrencyCodes.includes(code.toUpperCase())) {
100
111
  throw new Error('Unsupported XRP issued-currency code: signing must preserve its exact identity');
101
112
  }
102
113
  if (!isValidClassicAddress(issuer)) {
@@ -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"}
@@ -26,4 +26,22 @@ export type TonAddressBounceability = 'bounceable' | 'nonBounceable' | 'unspecif
26
26
  * declared — leaving the caller to pick the safe default for its own context.
27
27
  */
28
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;
29
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":"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"}
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"}
@@ -42,4 +42,34 @@ export const getTonAddressBounceability = (address) => {
42
42
  }
43
43
  return parsed.data.isBounceable ? 'bounceable' : 'nonBounceable';
44
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();
45
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,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,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;AASD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,OAAe,EAA2B,EAAE;IACrF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;IAE5D,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QACtB,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAA;AAClE,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,9 @@
1
+ /**
2
+ * Collapses a jetton 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
+ */
8
+ export declare const normalizeJettonSymbol: (value: string) => string;
9
+ //# sourceMappingURL=symbol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/ton/jetton/symbol.ts"],"names":[],"mappings":"AAmDA;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,KAAG,MAIxB,CAAA"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Homoglyphs scammers substitute into a jetton 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 jetton 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
+ */
57
+ export const normalizeJettonSymbol = (value) => Array.from(value.normalize('NFKD').replace(combiningMarks, '').toUpperCase())
58
+ .map(char => confusables[char] ?? char)
59
+ .join('')
60
+ .replace(/[^A-Z0-9]/g, '');
61
+ //# sourceMappingURL=symbol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/ton/jetton/symbol.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;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAU,EAAE,CAC7D,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"}