@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.
- package/CHANGELOG.md +90 -0
- package/dist/Chain.d.ts +0 -4
- package/dist/Chain.d.ts.map +1 -1
- package/dist/Chain.js +0 -1
- package/dist/Chain.js.map +1 -1
- package/dist/ChainKind.d.ts +0 -1
- package/dist/ChainKind.d.ts.map +1 -1
- package/dist/ChainKind.js +0 -1
- package/dist/ChainKind.js.map +1 -1
- package/dist/chainRegistry.d.ts +0 -1
- package/dist/chainRegistry.d.ts.map +1 -1
- package/dist/chainRegistry.js +0 -1
- package/dist/chainRegistry.js.map +1 -1
- package/dist/chains/cosmos/account/getCosmosAccountInfo.d.ts.map +1 -1
- package/dist/chains/cosmos/account/getCosmosAccountInfo.js +0 -5
- package/dist/chains/cosmos/account/getCosmosAccountInfo.js.map +1 -1
- package/dist/chains/cosmos/chainInfo.d.ts.map +1 -1
- package/dist/chains/cosmos/chainInfo.js +0 -1
- package/dist/chains/cosmos/chainInfo.js.map +1 -1
- package/dist/chains/cosmos/cosmosFeeCoinDenom.d.ts.map +1 -1
- package/dist/chains/cosmos/cosmosFeeCoinDenom.js +0 -1
- package/dist/chains/cosmos/cosmosFeeCoinDenom.js.map +1 -1
- package/dist/chains/cosmos/cosmosGasLimitRecord.d.ts.map +1 -1
- package/dist/chains/cosmos/cosmosGasLimitRecord.js +0 -2
- package/dist/chains/cosmos/cosmosGasLimitRecord.js.map +1 -1
- package/dist/chains/cosmos/cosmosMemoCap.d.ts.map +1 -1
- package/dist/chains/cosmos/cosmosMemoCap.js +0 -1
- package/dist/chains/cosmos/cosmosMemoCap.js.map +1 -1
- package/dist/chains/cosmos/cosmosRpcUrl.d.ts.map +1 -1
- package/dist/chains/cosmos/cosmosRpcUrl.js +0 -3
- package/dist/chains/cosmos/cosmosRpcUrl.js.map +1 -1
- package/dist/chains/cosmos/gas.d.ts.map +1 -1
- package/dist/chains/cosmos/gas.js +0 -1
- package/dist/chains/cosmos/gas.js.map +1 -1
- package/dist/chains/cosmos/tendermintRpcUrl.d.ts.map +1 -1
- package/dist/chains/cosmos/tendermintRpcUrl.js +0 -1
- package/dist/chains/cosmos/tendermintRpcUrl.js.map +1 -1
- package/dist/chains/cosmos/thor/thorchainLp.d.ts.map +1 -1
- package/dist/chains/cosmos/thor/thorchainLp.js +0 -1
- package/dist/chains/cosmos/thor/thorchainLp.js.map +1 -1
- package/dist/chains/ripple/issuedCurrency.d.ts +13 -3
- package/dist/chains/ripple/issuedCurrency.d.ts.map +1 -1
- package/dist/chains/ripple/issuedCurrency.js +65 -6
- package/dist/chains/ripple/issuedCurrency.js.map +1 -1
- package/dist/chains/ripple/trustLine.d.ts +22 -0
- package/dist/chains/ripple/trustLine.d.ts.map +1 -0
- package/dist/chains/ripple/trustLine.js +14 -0
- package/dist/chains/ripple/trustLine.js.map +1 -0
- package/dist/chains/ton/address.d.ts +32 -0
- package/dist/chains/ton/address.d.ts.map +1 -1
- package/dist/chains/ton/address.js +45 -0
- package/dist/chains/ton/address.js.map +1 -1
- package/dist/chains/ton/api.d.ts +49 -0
- package/dist/chains/ton/api.d.ts.map +1 -1
- package/dist/chains/ton/api.js +131 -24
- package/dist/chains/ton/api.js.map +1 -1
- package/dist/chains/ton/comment.d.ts +51 -0
- package/dist/chains/ton/comment.d.ts.map +1 -0
- package/dist/chains/ton/comment.js +75 -0
- package/dist/chains/ton/comment.js.map +1 -0
- package/dist/chains/ton/jetton/symbol.d.ts +9 -0
- package/dist/chains/ton/jetton/symbol.d.ts.map +1 -0
- package/dist/chains/ton/jetton/symbol.js +61 -0
- package/dist/chains/ton/jetton/symbol.js.map +1 -0
- package/dist/chains/ton/jetton/verification.d.ts +35 -0
- package/dist/chains/ton/jetton/verification.d.ts.map +1 -0
- package/dist/chains/ton/jetton/verification.js +45 -0
- package/dist/chains/ton/jetton/verification.js.map +1 -0
- package/dist/chains/ton/jetton/verifiedRegistry.d.ts +43 -0
- package/dist/chains/ton/jetton/verifiedRegistry.d.ts.map +1 -0
- package/dist/chains/ton/jetton/verifiedRegistry.js +94 -0
- package/dist/chains/ton/jetton/verifiedRegistry.js.map +1 -0
- package/dist/chains/ton/messageBounce.d.ts +17 -0
- package/dist/chains/ton/messageBounce.d.ts.map +1 -0
- package/dist/chains/ton/messageBounce.js +41 -0
- package/dist/chains/ton/messageBounce.js.map +1 -0
- package/dist/chains/tron/getTronBlockInfo.d.ts.map +1 -1
- package/dist/chains/tron/getTronBlockInfo.js +4 -5
- package/dist/chains/tron/getTronBlockInfo.js.map +1 -1
- package/dist/coin/balance/resolvers/ripple.d.ts.map +1 -1
- package/dist/coin/balance/resolvers/ripple.js +3 -2
- package/dist/coin/balance/resolvers/ripple.js.map +1 -1
- package/dist/coin/chainFeeCoin.d.ts.map +1 -1
- package/dist/coin/chainFeeCoin.js +0 -5
- package/dist/coin/chainFeeCoin.js.map +1 -1
- package/dist/coin/coinType.d.ts.map +1 -1
- package/dist/coin/coinType.js +0 -1
- package/dist/coin/coinType.js.map +1 -1
- package/dist/coin/find/CoinFinderChainKind.d.ts +1 -1
- package/dist/coin/find/CoinFinderChainKind.d.ts.map +1 -1
- package/dist/coin/find/CoinFinderChainKind.js +1 -1
- package/dist/coin/find/CoinFinderChainKind.js.map +1 -1
- package/dist/coin/find/index.d.ts.map +1 -1
- package/dist/coin/find/index.js +2 -0
- package/dist/coin/find/index.js.map +1 -1
- package/dist/coin/find/resolvers/ton.d.ts +15 -0
- package/dist/coin/find/resolvers/ton.d.ts.map +1 -0
- package/dist/coin/find/resolvers/ton.js +61 -0
- package/dist/coin/find/resolvers/ton.js.map +1 -0
- package/dist/coin/knownTokens/cosmos.d.ts.map +1 -1
- package/dist/coin/knownTokens/cosmos.js +0 -64
- package/dist/coin/knownTokens/cosmos.js.map +1 -1
- package/dist/coin/knownTokens/index.d.ts +1 -1
- package/dist/coin/knownTokens/index.d.ts.map +1 -1
- package/dist/coin/token/metadata/chains.d.ts +1 -1
- package/dist/coin/token/metadata/chains.d.ts.map +1 -1
- package/dist/coin/tokenVerification.d.ts +13 -0
- package/dist/coin/tokenVerification.d.ts.map +1 -0
- package/dist/coin/tokenVerification.js +12 -0
- package/dist/coin/tokenVerification.js.map +1 -0
- package/dist/swap/general/swapkit/SwapKitEnabledChains.d.ts +14 -3
- package/dist/swap/general/swapkit/SwapKitEnabledChains.d.ts.map +1 -1
- package/dist/swap/general/swapkit/SwapKitEnabledChains.js +14 -1
- package/dist/swap/general/swapkit/SwapKitEnabledChains.js.map +1 -1
- package/dist/swap/general/swapkit/SwapKitProviders.d.ts +19 -3
- package/dist/swap/general/swapkit/SwapKitProviders.d.ts.map +1 -1
- package/dist/swap/general/swapkit/SwapKitProviders.js +161 -8
- package/dist/swap/general/swapkit/SwapKitProviders.js.map +1 -1
- package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts +1 -3
- package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
- package/dist/swap/general/swapkit/api/getSwapKitQuote.js +148 -78
- package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.d.ts +2 -1
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.d.ts.map +1 -1
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.js +2 -1
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.js.map +1 -1
- package/dist/swap/native/NativeSwapChain.d.ts +1 -2
- package/dist/swap/native/NativeSwapChain.d.ts.map +1 -1
- package/dist/swap/native/NativeSwapChain.js +0 -2
- package/dist/swap/native/NativeSwapChain.js.map +1 -1
- package/dist/swap/native/limitSwapMemo.d.ts.map +1 -1
- package/dist/swap/native/limitSwapMemo.js +18 -5
- package/dist/swap/native/limitSwapMemo.js.map +1 -1
- package/dist/swap/native/thorchainMemoAsset.d.ts +1 -1
- package/dist/swap/native/thorchainMemoAsset.js +1 -1
- package/dist/swap/quote/findSwapQuote.d.ts.map +1 -1
- package/dist/swap/quote/findSwapQuote.js +2 -2
- package/dist/swap/quote/findSwapQuote.js.map +1 -1
- package/dist/swap/skip/skipRouting.d.ts.map +1 -1
- package/dist/swap/skip/skipRouting.js +0 -1
- package/dist/swap/skip/skipRouting.js.map +1 -1
- package/dist/swap/swapEnabledChains.d.ts +1 -1
- package/dist/swap/swapEnabledChains.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/tron.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/tron.js +6 -1
- package/dist/tx/broadcast/resolvers/tron.js.map +1 -1
- package/dist/tx/broadcast/verifyBroadcastByHash.js +1 -1
- package/dist/tx/broadcast/verifyBroadcastByHash.js.map +1 -1
- package/dist/tx/status/resolver.d.ts +9 -1
- package/dist/tx/status/resolver.d.ts.map +1 -1
- package/dist/tx/status/resolvers/ripple.d.ts.map +1 -1
- package/dist/tx/status/resolvers/ripple.js +62 -0
- package/dist/tx/status/resolvers/ripple.js.map +1 -1
- package/dist/tx/status/resolvers/tron.d.ts.map +1 -1
- package/dist/tx/status/resolvers/tron.js +18 -2
- package/dist/tx/status/resolvers/tron.js.map +1 -1
- 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;
|
|
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 =
|
|
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
|
|
20
|
-
.toString('
|
|
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.
|
|
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
|
|
83
|
-
* fixed on-chain decimal count.
|
|
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":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
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":"
|
|
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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"}
|
package/dist/chains/ton/api.d.ts
CHANGED
|
@@ -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":"
|
|
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"}
|
package/dist/chains/ton/api.js
CHANGED
|
@@ -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 {
|
|
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 =
|
|
17
|
-
const rawMaster =
|
|
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
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAE9C,MAAM,SAAS,GAAG,GAAG,UAAU,MAAM,CAAA;AAoDrC,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAE,QAAgB,EAAW,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAA;AAEtH;;;;;;;;GAQG;AACH,MAAM,sBAAsB,GAAG,KAAK,EAAE,EACpC,YAAY,EACZ,mBAAmB,GACE,EAGpB,EAAE;IACH,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CAAA;IAEzD,MAAM,GAAG,GAAG,GAAG,SAAS,oCAAoC,QAAQ,mBAAmB,SAAS,EAAE,CAAA;IAClG,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAuB,GAAG,CAAC,CAAA;IAE1D,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CACzC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAClG,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,YAAY,EAAE,CAAA;AACvD,CAAC,CAAA;AAED,4FAA4F;AAC5F,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,KAA2B,EAAmB,EAAE;IAC3F,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACnE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC3C,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,IAAI,MAAM,CAAC,OAAO,CAAA;AACrE,CAAC,CAAA;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,KAA2B,EAAmB,EAAE;IACrF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAA;IAEtD,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC,CAAA;AACvC,CAAC,CAAA;AAOD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAAe,EAAmB,EAAE;IAC1E,MAAM,GAAG,GAAG,GAAG,SAAS,kCAAkC,OAAO,eAAe,CAAA;IAChF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAA6B,GAAG,CAAC,CAAA;IAEhE,OAAO,QAAQ,CAAC,MAAM,CAAA;AACxB,CAAC,CAAA;AAsCD,MAAM,QAAQ,GAAG,CAAC,KAAyB,EAAsB,EAAE;IACjE,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;IAC7B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;AACtC,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,KAAyB,EAAsB,EAAE;IACtE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAEzC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAElC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AACrD,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,CAAC,QAAqC,EAAE,OAAe,EAA+B,EAAE,CACnH,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,CACnC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAC/F,CAAA;AAQH;;;;;;;GAOG;AACH,MAAM,yBAAyB,GAAG,CAAC,EACjC,OAAO,EACP,OAAO,EACP,OAAO,GACwB,EAAwB,EAAE;IACzD,MAAM,IAAI,GACR,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC;QACvC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC;QACtC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC;QACpC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAE1B,OAAO;QACL,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC;QACpC,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAC9D,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;QACxD,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,CAAC;QACtE,IAAI;QACJ,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;KAC9E,CAAA;AACH,CAAC,CAAA;AAQD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,mBAA2B,EAA6B,EAAE;IAClG,MAAM,GAAG,GAAG,GAAG,SAAS,8BAA8B,kBAAkB,CAAC,mBAAmB,CAAC,UAAU,CAAA;IACvG,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAwB,GAAG,CAAC,CAAA;IAE3D,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,8BAA8B,mBAAmB,EAAE,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,yBAAyB,CAAC;QAC3D,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC;QAChE,OAAO,EAAE,MAAM,CAAC,cAAc;KAC/B,CAAC,CAAA;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,mBAAmB,gBAAgB,CAAC,CAAA;IACvE,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;AAC1D,CAAC,CAAA;AAED,4EAA4E;AAC5E,4EAA4E;AAC5E,MAAM,uBAAuB,GAAG,EAAE,CAAA;AAElC;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAC3C,qBAA+B,EACgB,EAAE;IACjD,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAA;IAChF,MAAM,MAAM,GAAyC,EAAE,CAAA;IAEvD,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,YAAY,EAAE,uBAAuB,CAAC,EAAE,CAAC;QACrE,MAAM,GAAG,GAAG,GAAG,SAAS,8BAA8B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,MAAM,EAAE,CAAA;QAC7F,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAwB,GAAG,CAAC,CAAA;QAE3D,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,yBAAyB,CAAC;gBACzC,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC;gBAChE,OAAO,EAAE,MAAM,CAAC,cAAc;aAC/B,CAAC,CAAA;YACF,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAA;QACrC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAiBD,MAAM,0BAA0B,GAAG,GAAG,CAAA;AAEtC,kFAAkF;AAClF,mFAAmF;AACnF,wBAAwB;AACxB,MAAM,0BAA0B,GAAG,EAAE,CAAA;AAErC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EAAE,YAAoB,EAA+B,EAAE;IAC/F,mFAAmF;IACnF,iFAAiF;IACjF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAA;IACjD,MAAM,OAAO,GAAwB,EAAE,CAAA;IACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IACrC,MAAM,OAAO,GAAyC,EAAE,CAAA;IACxD,MAAM,qBAAqB,GAA2B,EAAE,CAAA;IAExD,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,0BAA0B,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,GAAG,0BAA0B,CAAA;QAChD,MAAM,GAAG,GAAG,GAAG,SAAS,oCAAoC,QAAQ,oCAAoC,0BAA0B,WAAW,MAAM,EAAE,CAAA;QACrJ,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAuB,GAAG,CAAC,CAAA;QAC1D,MAAM,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAA;QAE1C,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC7C,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC;gBAAE,SAAQ;YAExD,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YAC7D,IAAI,WAAW,CAAC,GAAG,CAAC,mBAAmB,CAAC;gBAAE,SAAQ;YAElD,WAAW,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;YACpC,OAAO,CAAC,IAAI,CAAC,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAA;YAE7E,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACtE,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,mBAAmB,CAAC,GAAG,yBAAyB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;YAC/F,CAAC;YAED,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,CAAA;YAC1E,IAAI,YAAY,EAAE,CAAC;gBACjB,qBAAqB,CAAC,mBAAmB,CAAC,GAAG,YAAY,CAAA;YAC3D,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,GAAG,0BAA0B,CAAA;QAC9E,IAAI,UAAU,IAAI,WAAW,CAAC,IAAI,KAAK,iBAAiB;YAAE,MAAK;IACjE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAA;AACpD,CAAC,CAAA"}
|
|
@@ -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
|