@vultisig/core-chain 5.0.0 → 5.2.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 +64 -0
- package/dist/chains/ripple/issuedCurrency.d.ts.map +1 -1
- package/dist/chains/ripple/issuedCurrency.js +15 -4
- 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 +18 -0
- package/dist/chains/ton/address.d.ts.map +1 -1
- package/dist/chains/ton/address.js +30 -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/failure.d.ts +70 -0
- package/dist/chains/ton/failure.d.ts.map +1 -0
- package/dist/chains/ton/failure.js +170 -0
- package/dist/chains/ton/failure.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/wallet.d.ts +50 -0
- package/dist/chains/ton/wallet.d.ts.map +1 -0
- package/dist/chains/ton/wallet.js +54 -0
- package/dist/chains/ton/wallet.js.map +1 -0
- package/dist/chains/ton/walletV5R1.d.ts +27 -0
- package/dist/chains/ton/walletV5R1.d.ts.map +1 -0
- package/dist/chains/ton/walletV5R1.js +53 -0
- package/dist/chains/ton/walletV5R1.js.map +1 -0
- 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/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/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/publicKey/address/deriveAddress.d.ts +8 -1
- package/dist/publicKey/address/deriveAddress.d.ts.map +1 -1
- package/dist/publicKey/address/deriveAddress.js +5 -1
- package/dist/publicKey/address/deriveAddress.js.map +1 -1
- package/dist/publicKey/address/getChainAddress.d.ts +4 -1
- package/dist/publicKey/address/getChainAddress.d.ts.map +1 -1
- package/dist/publicKey/address/getChainAddress.js +2 -2
- package/dist/publicKey/address/getChainAddress.js.map +1 -1
- package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
- package/dist/swap/general/swapkit/api/getSwapKitQuote.js +89 -5
- package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
- package/dist/tx/broadcast/resolvers/ton.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/ton.js +8 -0
- package/dist/tx/broadcast/resolvers/ton.js.map +1 -1
- package/dist/tx/status/index.d.ts +2 -2
- package/dist/tx/status/index.d.ts.map +1 -1
- package/dist/tx/status/resolver.d.ts +15 -0
- package/dist/tx/status/resolver.d.ts.map +1 -1
- package/dist/tx/status/resolvers/ton.d.ts +5 -1
- package/dist/tx/status/resolvers/ton.d.ts.map +1 -1
- package/dist/tx/status/resolvers/ton.js +8 -29
- package/dist/tx/status/resolvers/ton.js.map +1 -1
- package/package.json +46 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Address } from '@ton/core';
|
|
2
|
+
import { getTonV5R1Address, tonV5R1WalletId } from '@vultisig/core-chain/chains/ton/walletV5R1';
|
|
3
|
+
import { match } from '@vultisig/lib-utils/match';
|
|
4
|
+
/**
|
|
5
|
+
* The wallet contracts a Vultisig TON account can live in. The same Ed25519
|
|
6
|
+
* key yields a different address under each, so they are different accounts.
|
|
7
|
+
*/
|
|
8
|
+
export const tonWalletVersions = ['v4r2', 'v5r1'];
|
|
9
|
+
/**
|
|
10
|
+
* The contract every Vultisig TON address has been derived from so far. W5 is
|
|
11
|
+
* an explicit opt-in: switching a key's default would silently move the user
|
|
12
|
+
* to an empty account.
|
|
13
|
+
*/
|
|
14
|
+
export const defaultTonWalletVersion = 'v4r2';
|
|
15
|
+
export { tonV5R1WalletId };
|
|
16
|
+
/**
|
|
17
|
+
* How many outgoing messages one external request may carry. V4 is limited by
|
|
18
|
+
* the wallet code; W5 by the 255-entry action list.
|
|
19
|
+
*/
|
|
20
|
+
export const tonMaxMessagesPerRequest = { v4r2: 4, v5r1: 255 };
|
|
21
|
+
/**
|
|
22
|
+
* The user-friendly, non-bounceable (`UQ…`) address of this key's wallet
|
|
23
|
+
* under the given contract. V4R2 is WalletCore's own TON derivation; W5 is the
|
|
24
|
+
* hash of the StateInit the contract is deployed from, built with `@ton/core`
|
|
25
|
+
* from the key bytes alone — no WalletCore feature beyond the public key, so it
|
|
26
|
+
* also works on React Native, whose native bridge exposes no `TONWallet`.
|
|
27
|
+
*/
|
|
28
|
+
export const deriveTonAddress = ({ publicKey, walletCore, version }) => match(version, {
|
|
29
|
+
v4r2: () => walletCore.CoinTypeExt.deriveAddressFromPublicKey(walletCore.CoinType.ton, publicKey),
|
|
30
|
+
v5r1: () => getTonV5R1Address({ publicKey: publicKey.data() }).toString({
|
|
31
|
+
bounceable: false,
|
|
32
|
+
testOnly: false,
|
|
33
|
+
urlSafe: true,
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Which wallet contract an address is, for this key.
|
|
38
|
+
*
|
|
39
|
+
* The keysign payload carries no wallet-version field, so the sender address
|
|
40
|
+
* is the contract's identity: every co-signer derives both candidate addresses
|
|
41
|
+
* from the shared vault key and matches. An address that is neither is refused
|
|
42
|
+
* rather than assumed V4R2 — signing a V4R2 request for a wallet that is not
|
|
43
|
+
* one would either be rejected on chain or, worse, accepted by a contract we
|
|
44
|
+
* never meant to drive.
|
|
45
|
+
*/
|
|
46
|
+
export const resolveTonWalletVersion = ({ address, publicKey, walletCore }) => {
|
|
47
|
+
const account = Address.parse(address);
|
|
48
|
+
const version = tonWalletVersions.find(candidate => Address.parse(deriveTonAddress({ publicKey, walletCore, version: candidate })).equals(account));
|
|
49
|
+
if (!version) {
|
|
50
|
+
throw new Error(`TON address ${address} is not this key's V4R2 or W5 wallet; refusing to sign for an unknown wallet contract`);
|
|
51
|
+
}
|
|
52
|
+
return version;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAC/F,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAU,CAAA;AAI1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAqB,MAAM,CAAA;AAE/D,OAAO,EAAE,eAAe,EAAE,CAAA;AAE1B;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAqC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAA;AAQhG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAyB,EAAU,EAAE,CACpG,KAAK,CAAC,OAAO,EAAE;IACb,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,0BAA0B,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACjG,IAAI,EAAE,GAAG,EAAE,CACT,iBAAiB,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC;QAC1D,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,IAAI;KACd,CAAC;CACL,CAAC,CAAA;AAQJ;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAgC,EAAE,EAAE;IAC1G,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEtC,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CACjD,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAC/F,CAAA;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,eAAe,OAAO,uFAAuF,CAC9G,CAAA;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Address, StateInit } from '@ton/core';
|
|
2
|
+
/**
|
|
3
|
+
* W5R1 wallet id on mainnet, as the contract stores it: the network's global
|
|
4
|
+
* id (-239) XOR'd with the client context `1 | workchain 0 | version 0 |
|
|
5
|
+
* subwallet 0` (0x80000000), giving 0x7FFFFF11. WalletCore hardcodes this
|
|
6
|
+
* value for `WALLET_V5_R1`, so it is the only id that can be co-signed.
|
|
7
|
+
*/
|
|
8
|
+
export declare const tonV5R1WalletId = 2147483409;
|
|
9
|
+
type BuildTonV5R1StateInitInput = {
|
|
10
|
+
/** The wallet's Ed25519 public key, 32 bytes. */
|
|
11
|
+
publicKey: Uint8Array;
|
|
12
|
+
/** Defaults to the mainnet id WalletCore uses. */
|
|
13
|
+
walletId?: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The W5R1 StateInit for a key: the published code cell plus the data cell
|
|
17
|
+
* `is_signature_allowed(1)=1 || seqno(32)=0 || wallet_id(int32) || publicKey(256) || bit(0)`
|
|
18
|
+
* (an empty extensions dictionary). Byte-identical to WalletCore's
|
|
19
|
+
* `WalletV5R1::state_init_impl`, but built from `@ton/core` alone so it runs
|
|
20
|
+
* wherever the key bytes are available — including React Native, whose native
|
|
21
|
+
* WalletCore bridge has no `TONWallet`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const buildTonV5R1StateInit: ({ publicKey, walletId, }: BuildTonV5R1StateInitInput) => StateInit;
|
|
24
|
+
/** The W5R1 wallet address (workchain 0) for a key: the hash of its StateInit. */
|
|
25
|
+
export declare const getTonV5R1Address: (input: BuildTonV5R1StateInitInput) => Address;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=walletV5R1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walletV5R1.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/walletV5R1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAoC,SAAS,EAAE,MAAM,WAAW,CAAA;AAYhF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,aAAa,CAAA;AAiBzC,KAAK,0BAA0B,GAAG;IAChC,iDAAiD;IACjD,SAAS,EAAE,UAAU,CAAA;IACrB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,0BAGnC,0BAA0B,KAAG,SAc/B,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,GAAI,OAAO,0BAA0B,KAAG,OACR,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { beginCell, Cell, contractAddress } from '@ton/core';
|
|
2
|
+
import { Buffer } from 'buffer';
|
|
3
|
+
/**
|
|
4
|
+
* Wallet V5R1 (W5) compiled code cell, base64 — the StateInit WalletCore 4.7
|
|
5
|
+
* emits for `WALLET_V5_R1`, code hash
|
|
6
|
+
* 20834b7b72b112147e1b2fb457b84e74d1a30f04f737d4f62a668e9552d2b72f, the
|
|
7
|
+
* published W5R1 mainnet code. Keep it copy-paste identical; do not reformat.
|
|
8
|
+
*/
|
|
9
|
+
const walletV5R1CodeBase64 = 'te6cckECFAEAAoEAART/APSkE/S88sgLAQIBIAINAgFIAwQC3NAg10nBIJFbj2Mg1wsfIIIQZXh0br0hghBzaW50vbCSXwPgghBleHRuuo60gCDXIQHQdNch+kAw+kT4KPpEMFi9kVvg7UTQgQFB1yH0BYMH9A5voTGRMOGAQNchcH/bPOAxINdJgQKAuZEw4HDiEA8CASAFDAIBIAYJAgFuBwgAGa3OdqJoQCDrkOuF/8AAGa8d9qJoQBDrkOuFj8ACAUgKCwAXsyX7UTQcdch1wsfgABGyYvtRNDXCgCAAGb5fD2omhAgKDrkPoCwBAvIOAR4g1wsfghBzaWduuvLgin8PAeaO8O2i7fshgwjXIgKDCNcjIIAg1yHTH9Mf0x/tRNDSANMfINMf0//XCgAK+QFAzPkQmiiUXwrbMeHywIffArNQB7Dy0IRRJbry4IVQNrry4Ib4I7vy0IgikvgA3gGkf8jKAMsfAc8Wye1UIJL4D95w2zzYEAP27aLt+wL0BCFukmwhjkwCIdc5MHCUIccAs44tAdcoIHYeQ2wg10nACPLgkyDXSsAC8uCTINcdBscSwgBSMLDy0InXTNc5MAGk6GwShAe78uCT10rAAPLgk+1V4tIAAcAAkVvg69csCBQgkXCWAdcsCBwS4lIQseMPINdKERITAJYB+kAB+kT4KPpEMFi68uCR7UTQgQFB1xj0BQSdf8jKAEAEgwf0U/Lgi44UA4MH9Fvy4Iwi1woAIW4Bs7Dy0JDiyFADzxYS9ADJ7VQAcjDXLAgkji0h8uCS0gDtRNDSAFETuvLQj1RQMJExnAGBAUDXIdcKAPLgjuLIygBYzxbJ7VST8sCN4gAQk1vbMeHXTNC01sNe';
|
|
10
|
+
/**
|
|
11
|
+
* W5R1 wallet id on mainnet, as the contract stores it: the network's global
|
|
12
|
+
* id (-239) XOR'd with the client context `1 | workchain 0 | version 0 |
|
|
13
|
+
* subwallet 0` (0x80000000), giving 0x7FFFFF11. WalletCore hardcodes this
|
|
14
|
+
* value for `WALLET_V5_R1`, so it is the only id that can be co-signed.
|
|
15
|
+
*/
|
|
16
|
+
export const tonV5R1WalletId = 2147483409;
|
|
17
|
+
const baseWorkchain = 0;
|
|
18
|
+
let cachedCodeCell;
|
|
19
|
+
/** Parsed on first use: `Cell.fromBoc` needs the Buffer polyfill, which a React Native entry installs at startup. */
|
|
20
|
+
const getWalletV5R1CodeCell = () => {
|
|
21
|
+
if (!cachedCodeCell) {
|
|
22
|
+
const [cell] = Cell.fromBoc(Buffer.from(walletV5R1CodeBase64, 'base64'));
|
|
23
|
+
if (!cell) {
|
|
24
|
+
throw new Error('TON W5 code cell failed to parse');
|
|
25
|
+
}
|
|
26
|
+
cachedCodeCell = cell;
|
|
27
|
+
}
|
|
28
|
+
return cachedCodeCell;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The W5R1 StateInit for a key: the published code cell plus the data cell
|
|
32
|
+
* `is_signature_allowed(1)=1 || seqno(32)=0 || wallet_id(int32) || publicKey(256) || bit(0)`
|
|
33
|
+
* (an empty extensions dictionary). Byte-identical to WalletCore's
|
|
34
|
+
* `WalletV5R1::state_init_impl`, but built from `@ton/core` alone so it runs
|
|
35
|
+
* wherever the key bytes are available — including React Native, whose native
|
|
36
|
+
* WalletCore bridge has no `TONWallet`.
|
|
37
|
+
*/
|
|
38
|
+
export const buildTonV5R1StateInit = ({ publicKey, walletId = tonV5R1WalletId, }) => {
|
|
39
|
+
if (publicKey.length !== 32) {
|
|
40
|
+
throw new Error(`TON Ed25519 public key must be 32 bytes, got ${publicKey.length}`);
|
|
41
|
+
}
|
|
42
|
+
const data = beginCell()
|
|
43
|
+
.storeBit(true)
|
|
44
|
+
.storeUint(0, 32)
|
|
45
|
+
.storeInt(walletId, 32)
|
|
46
|
+
.storeBuffer(Buffer.from(publicKey))
|
|
47
|
+
.storeBit(false)
|
|
48
|
+
.endCell();
|
|
49
|
+
return { code: getWalletV5R1CodeCell(), data };
|
|
50
|
+
};
|
|
51
|
+
/** The W5R1 wallet address (workchain 0) for a key: the hash of its StateInit. */
|
|
52
|
+
export const getTonV5R1Address = (input) => contractAddress(baseWorkchain, buildTonV5R1StateInit(input));
|
|
53
|
+
//# sourceMappingURL=walletV5R1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walletV5R1.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/walletV5R1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,SAAS,EAAE,IAAI,EAAE,eAAe,EAAa,MAAM,WAAW,CAAA;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B;;;;;GAKG;AACH,MAAM,oBAAoB,GACxB,82BAA82B,CAAA;AAEh3B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAA;AAEzC,MAAM,aAAa,GAAG,CAAC,CAAA;AAEvB,IAAI,cAAgC,CAAA;AACpC,qHAAqH;AACrH,MAAM,qBAAqB,GAAG,GAAS,EAAE;IACvC,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC,CAAA;QACxE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;QACrD,CAAC;QACD,cAAc,GAAG,IAAI,CAAA;IACvB,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC,CAAA;AASD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EACpC,SAAS,EACT,QAAQ,GAAG,eAAe,GACC,EAAa,EAAE;IAC1C,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,gDAAgD,SAAS,CAAC,MAAM,EAAE,CAAC,CAAA;IACrF,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,EAAE;SACrB,QAAQ,CAAC,IAAI,CAAC;SACd,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;SAChB,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC;SACtB,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SACnC,QAAQ,CAAC,KAAK,CAAC;SACf,OAAO,EAAE,CAAA;IAEZ,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,IAAI,EAAE,CAAA;AAChD,CAAC,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAiC,EAAW,EAAE,CAC9E,eAAe,CAAC,aAAa,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/balance/resolvers/ripple.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/balance/resolvers/ripple.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAmCjD;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,4BAA4B,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,yBAAyB,CAsCrG,CAAA;AAQD,eAAO,MAAM,oBAAoB,EAAE,mBAM3B,CAAA"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getRippleAccountInfo } from '@vultisig/core-chain/chains/ripple/account/info';
|
|
2
2
|
import { getRippleAccountLines } from '@vultisig/core-chain/chains/ripple/account/lines';
|
|
3
|
-
import { parseIssuedCurrencyValue, parseRippleTokenId
|
|
3
|
+
import { parseIssuedCurrencyValue, parseRippleTokenId } from '@vultisig/core-chain/chains/ripple/issuedCurrency';
|
|
4
4
|
import { getRippleNetworkInfo } from '@vultisig/core-chain/chains/ripple/network/info';
|
|
5
|
+
import { findRippleTrustLine } from '@vultisig/core-chain/chains/ripple/trustLine';
|
|
5
6
|
import { isFeeCoin } from '@vultisig/core-chain/coin/utils/isFeeCoin';
|
|
6
7
|
import { shouldBePresent } from '@vultisig/lib-utils/assert/shouldBePresent';
|
|
7
8
|
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
@@ -24,7 +25,7 @@ const getRippleIssuedCurrencyBalance = async ({ address, id }) => {
|
|
|
24
25
|
}
|
|
25
26
|
throw linesResult.error;
|
|
26
27
|
}
|
|
27
|
-
const line = linesResult.data
|
|
28
|
+
const line = findRippleTrustLine({ lines: linesResult.data, currency, issuer });
|
|
28
29
|
if (!line) {
|
|
29
30
|
return BigInt(0);
|
|
30
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/balance/resolvers/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kDAAkD,CAAA;AACxF,OAAO,
|
|
1
|
+
{"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/balance/resolvers/ripple.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const coinFinderChainKinds: readonly ["evm", "cosmos", "solana", "cardano", "ripple"];
|
|
1
|
+
export declare const coinFinderChainKinds: readonly ["evm", "cosmos", "solana", "cardano", "ripple", "ton"];
|
|
2
2
|
export type CoinFinderChainKind = (typeof coinFinderChainKinds)[number];
|
|
3
3
|
//# sourceMappingURL=CoinFinderChainKind.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoinFinderChainKind.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/CoinFinderChainKind.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"CoinFinderChainKind.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/CoinFinderChainKind.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,kEAAmE,CAAA;AACpG,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const coinFinderChainKinds = ['evm', 'cosmos', 'solana', 'cardano', 'ripple'];
|
|
1
|
+
export const coinFinderChainKinds = ['evm', 'cosmos', 'solana', 'cardano', 'ripple', 'ton'];
|
|
2
2
|
//# sourceMappingURL=CoinFinderChainKind.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoinFinderChainKind.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/CoinFinderChainKind.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"CoinFinderChainKind.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/CoinFinderChainKind.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAKlD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAKlD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAiB9C,eAAO,MAAM,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAW9C,CAAA"}
|
package/dist/coin/find/index.js
CHANGED
|
@@ -6,12 +6,14 @@ import { findCosmosCoins } from './resolvers/cosmos.js';
|
|
|
6
6
|
import { findEvmCoins } from './resolvers/evm/index.js';
|
|
7
7
|
import { findRippleCoins } from './resolvers/ripple.js';
|
|
8
8
|
import { findSolanaCoins } from './resolvers/solana/index.js';
|
|
9
|
+
import { findTonCoins } from './resolvers/ton.js';
|
|
9
10
|
const resolvers = {
|
|
10
11
|
cosmos: findCosmosCoins,
|
|
11
12
|
evm: findEvmCoins,
|
|
12
13
|
solana: findSolanaCoins,
|
|
13
14
|
cardano: findCardanoCoins,
|
|
14
15
|
ripple: findRippleCoins,
|
|
16
|
+
ton: findTonCoins,
|
|
15
17
|
};
|
|
16
18
|
export const findCoins = async (input) => {
|
|
17
19
|
const chainKind = getChainKind(input.chain);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAA;AAE3D,OAAO,EAAuB,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/find/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAA;AAE3D,OAAO,EAAuB,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,SAAS,GAAwD;IACrE,MAAM,EAAE,eAAe;IACvB,GAAG,EAAE,YAAY;IACjB,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,gBAAgB;IACzB,MAAM,EAAE,eAAe;IACvB,GAAG,EAAE,YAAY;CAClB,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAA6B,KAAK,EAAC,KAAK,EAAC,EAAE;IAC/D,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3C,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,sCAAsC,SAAS,sBAAsB,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvG,CAAA;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IAErC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { OtherChain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { FindCoinsResolver } from '@vultisig/core-chain/coin/find/resolver';
|
|
3
|
+
/**
|
|
4
|
+
* Discovers the jettons held at `address` that pass verification.
|
|
5
|
+
*
|
|
6
|
+
* Only `verified` jettons are returned. TON wallets are carpet-bombed with
|
|
7
|
+
* airdropped counterfeits (fake USDT above all) and spam, and auto-adding those
|
|
8
|
+
* to a vault would put a "USDT" balance on the home screen that the user never
|
|
9
|
+
* received. Unverified and scam jettons can still be added by hand, where the
|
|
10
|
+
* UI labels them. Toncenter's indexer metadata rides along in the wallet
|
|
11
|
+
* listing, so no per-jetton call is needed; curated metadata wins for jettons
|
|
12
|
+
* we ship ourselves.
|
|
13
|
+
*/
|
|
14
|
+
export declare const findTonCoins: FindCoinsResolver<OtherChain.Ton>;
|
|
15
|
+
//# sourceMappingURL=ton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ton.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/find/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAMvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAA;AAM3E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC,GAAG,CA8C1D,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { tonAddressToBounceable } from '@vultisig/core-chain/chains/ton/address';
|
|
2
|
+
import { getOwnerJettonWallets } from '@vultisig/core-chain/chains/ton/api';
|
|
3
|
+
import { resolveTonJettonVerification } from '@vultisig/core-chain/chains/ton/jetton/verification';
|
|
4
|
+
import { getTonVerifiedJettonRegistry } from '@vultisig/core-chain/chains/ton/jetton/verifiedRegistry';
|
|
5
|
+
import { knownTokensIndex } from '@vultisig/core-chain/coin/knownTokens';
|
|
6
|
+
import { without } from '@vultisig/lib-utils/array/without';
|
|
7
|
+
const defaultJettonDecimals = 9;
|
|
8
|
+
/**
|
|
9
|
+
* Discovers the jettons held at `address` that pass verification.
|
|
10
|
+
*
|
|
11
|
+
* Only `verified` jettons are returned. TON wallets are carpet-bombed with
|
|
12
|
+
* airdropped counterfeits (fake USDT above all) and spam, and auto-adding those
|
|
13
|
+
* to a vault would put a "USDT" balance on the home screen that the user never
|
|
14
|
+
* received. Unverified and scam jettons can still be added by hand, where the
|
|
15
|
+
* UI labels them. Toncenter's indexer metadata rides along in the wallet
|
|
16
|
+
* listing, so no per-jetton call is needed; curated metadata wins for jettons
|
|
17
|
+
* we ship ourselves.
|
|
18
|
+
*/
|
|
19
|
+
export const findTonCoins = async ({ address, chain }) => {
|
|
20
|
+
const [{ wallets, masters, userFriendlyAddresses }, registry] = await Promise.all([
|
|
21
|
+
getOwnerJettonWallets(address),
|
|
22
|
+
getTonVerifiedJettonRegistry(),
|
|
23
|
+
]);
|
|
24
|
+
const coins = wallets.map(({ jettonMasterAddress, balance }) => {
|
|
25
|
+
if (balance <= 0n)
|
|
26
|
+
return;
|
|
27
|
+
const master = masters[jettonMasterAddress];
|
|
28
|
+
const verification = resolveTonJettonVerification({
|
|
29
|
+
address: jettonMasterAddress,
|
|
30
|
+
symbol: master?.symbol,
|
|
31
|
+
name: master?.name,
|
|
32
|
+
isFlaggedScam: master?.isFlaggedScam,
|
|
33
|
+
registry,
|
|
34
|
+
});
|
|
35
|
+
if (verification !== 'verified')
|
|
36
|
+
return;
|
|
37
|
+
const id = tonAddressToBounceable(userFriendlyAddresses[jettonMasterAddress] ?? jettonMasterAddress);
|
|
38
|
+
const known = knownTokensIndex[chain][id.toLowerCase()];
|
|
39
|
+
if (known) {
|
|
40
|
+
return { ...known, chain, id, address };
|
|
41
|
+
}
|
|
42
|
+
const verified = registry.byAddress[jettonMasterAddress];
|
|
43
|
+
if (!verified)
|
|
44
|
+
return;
|
|
45
|
+
const ticker = master?.symbol ?? verified.symbol;
|
|
46
|
+
if (!ticker)
|
|
47
|
+
return;
|
|
48
|
+
const priceProviderId = verified.priceProviderId;
|
|
49
|
+
return {
|
|
50
|
+
chain,
|
|
51
|
+
id,
|
|
52
|
+
address,
|
|
53
|
+
ticker,
|
|
54
|
+
decimals: master?.decimals ?? verified.decimals ?? defaultJettonDecimals,
|
|
55
|
+
logo: master?.logo ?? verified.logo,
|
|
56
|
+
...(priceProviderId === undefined ? {} : { priceProviderId }),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
return without(coins, undefined);
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=ton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/coin/find/resolvers/ton.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,qDAAqD,CAAA;AAClG,OAAO,EAAE,4BAA4B,EAAE,MAAM,yDAAyD,CAAA;AAGtG,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAA;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAA;AAE3D,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAE/B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAsC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;IAC1F,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChF,qBAAqB,CAAC,OAAO,CAAC;QAC9B,4BAA4B,EAAE;KAC/B,CAAC,CAAA;IAEF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAA2C,EAAE;QACtG,IAAI,OAAO,IAAI,EAAE;YAAE,OAAM;QAEzB,MAAM,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;QAC3C,MAAM,YAAY,GAAG,4BAA4B,CAAC;YAChD,OAAO,EAAE,mBAAmB;YAC5B,MAAM,EAAE,MAAM,EAAE,MAAM;YACtB,IAAI,EAAE,MAAM,EAAE,IAAI;YAClB,aAAa,EAAE,MAAM,EAAE,aAAa;YACpC,QAAQ;SACT,CAAC,CAAA;QACF,IAAI,YAAY,KAAK,UAAU;YAAE,OAAM;QAEvC,MAAM,EAAE,GAAG,sBAAsB,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,IAAI,mBAAmB,CAAC,CAAA;QAEpG,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;QACvD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,CAAA;QACzC,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;QACxD,IAAI,CAAC,QAAQ;YAAE,OAAM;QAErB,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAA;QAChD,IAAI,CAAC,MAAM;YAAE,OAAM;QAEnB,MAAM,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAA;QAEhD,OAAO;YACL,KAAK;YACL,EAAE;YACF,OAAO;YACP,MAAM;YACN,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,QAAQ,CAAC,QAAQ,IAAI,qBAAqB;YACxE,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI;YACnC,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;SAC9D,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;AAClC,CAAC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust tier a wallet can attach to a discovered or user-added token.
|
|
3
|
+
*
|
|
4
|
+
* - `verified`: listed in a curated registry we trust (our own known-token list
|
|
5
|
+
* or a chain ecosystem whitelist).
|
|
6
|
+
* - `scam`: positively identified as malicious, typically because it
|
|
7
|
+
* impersonates a verified token's symbol or name while living at a different
|
|
8
|
+
* contract address, or because the indexer flagged it.
|
|
9
|
+
* - `unverified`: neither — a real holding we know nothing about.
|
|
10
|
+
*/
|
|
11
|
+
export declare const tokenVerifications: readonly ["verified", "unverified", "scam"];
|
|
12
|
+
export type TokenVerification = (typeof tokenVerifications)[number];
|
|
13
|
+
//# sourceMappingURL=tokenVerification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenVerification.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/coin/tokenVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,6CAA8C,CAAA;AAE7E,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust tier a wallet can attach to a discovered or user-added token.
|
|
3
|
+
*
|
|
4
|
+
* - `verified`: listed in a curated registry we trust (our own known-token list
|
|
5
|
+
* or a chain ecosystem whitelist).
|
|
6
|
+
* - `scam`: positively identified as malicious, typically because it
|
|
7
|
+
* impersonates a verified token's symbol or name while living at a different
|
|
8
|
+
* contract address, or because the indexer flagged it.
|
|
9
|
+
* - `unverified`: neither — a real holding we know nothing about.
|
|
10
|
+
*/
|
|
11
|
+
export const tokenVerifications = ['verified', 'unverified', 'scam'];
|
|
12
|
+
//# sourceMappingURL=tokenVerification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenVerification.js","sourceRoot":"","sources":["../../../../../packages/core/chain/coin/tokenVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,CAAU,CAAA"}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { PublicKey, WalletCore } from '@trustwallet/wallet-core/dist/src/wallet-core';
|
|
2
2
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
3
|
+
import { TonWalletVersion } from '@vultisig/core-chain/chains/ton/wallet';
|
|
3
4
|
type DeriveAddressInput = {
|
|
4
5
|
chain: Chain;
|
|
5
6
|
publicKey: PublicKey;
|
|
6
7
|
walletCore: WalletCore;
|
|
8
|
+
/**
|
|
9
|
+
* TON only: which wallet contract to derive for. Defaults to V4R2, the
|
|
10
|
+
* contract every existing Vultisig TON address uses; W5 is a different
|
|
11
|
+
* account for the same key and must be an explicit choice.
|
|
12
|
+
*/
|
|
13
|
+
tonWalletVersion?: TonWalletVersion;
|
|
7
14
|
};
|
|
8
|
-
export declare const deriveAddress: ({ chain, publicKey, walletCore }: DeriveAddressInput) => string;
|
|
15
|
+
export declare const deriveAddress: ({ chain, publicKey, walletCore, tonWalletVersion }: DeriveAddressInput) => string;
|
|
9
16
|
export {};
|
|
10
17
|
//# sourceMappingURL=deriveAddress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveAddress.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/deriveAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"deriveAddress.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/deriveAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAA6C,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAMpH,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,SAAS,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC,CAAA;AAID,eAAO,MAAM,aAAa,GAAI,oDAAoD,kBAAkB,WAmCnG,CAAA"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { defaultTonWalletVersion, deriveTonAddress } from '@vultisig/core-chain/chains/ton/wallet';
|
|
2
3
|
import { getCoinType } from '@vultisig/core-chain/coin/coinType';
|
|
3
4
|
import { deriveBittensorAddress } from './bittensor.js';
|
|
4
5
|
import { deriveCardanoAddress } from './cardano.js';
|
|
5
6
|
const bitcoinCashPrefix = 'bitcoincash:';
|
|
6
|
-
export const deriveAddress = ({ chain, publicKey, walletCore }) => {
|
|
7
|
+
export const deriveAddress = ({ chain, publicKey, walletCore, tonWalletVersion }) => {
|
|
8
|
+
if (chain === Chain.Ton) {
|
|
9
|
+
return deriveTonAddress({ publicKey, walletCore, version: tonWalletVersion ?? defaultTonWalletVersion });
|
|
10
|
+
}
|
|
7
11
|
const coinType = getCoinType({
|
|
8
12
|
chain,
|
|
9
13
|
walletCore,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveAddress.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/deriveAddress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAEhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"deriveAddress.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/deriveAddress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAoB,MAAM,wCAAwC,CAAA;AACpH,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAEhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAchD,MAAM,iBAAiB,GAAG,cAAc,CAAA;AAExC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAsB,EAAE,EAAE;IACtG,IAAI,KAAK,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;QACxB,OAAO,gBAAgB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,CAAC,CAAA;IAC1G,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC;QAC3B,KAAK;QACL,UAAU;KACX,CAAC,CAAA;IAEF,IAAI,KAAK,KAAK,KAAK,CAAC,SAAS,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC,UAAU,CAAC,yBAAyB,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;IACnG,CAAC;IAED,IAAI,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,oBAAoB,CAAC;YAC1B,SAAS;YACT,UAAU;SACX,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,KAAK,CAAC,SAAS,EAAE,CAAC;QAC9B,OAAO,sBAAsB,CAAC;YAC5B,SAAS;YACT,UAAU;SACX,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,0BAA0B,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IAEtF,IAAI,KAAK,KAAK,KAAK,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACzE,OAAO,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { WalletCore } from '@trustwallet/wallet-core';
|
|
2
2
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
3
|
+
import { TonWalletVersion } from '@vultisig/core-chain/chains/ton/wallet';
|
|
3
4
|
import { PublicKeys } from '@vultisig/core-chain/publicKey/PublicKeys';
|
|
4
5
|
type GetChainAddressInput = {
|
|
5
6
|
chain: Chain;
|
|
@@ -8,8 +9,10 @@ type GetChainAddressInput = {
|
|
|
8
9
|
publicKeys: PublicKeys;
|
|
9
10
|
publicKeyMldsa?: string;
|
|
10
11
|
chainPublicKeys?: Partial<Record<Chain, string>>;
|
|
12
|
+
/** TON only: wallet contract to derive for. Defaults to V4R2. */
|
|
13
|
+
tonWalletVersion?: TonWalletVersion;
|
|
11
14
|
};
|
|
12
15
|
/** Derives the on-chain address for any chain, including MLDSA-based chains like QBTC. */
|
|
13
|
-
export declare const getChainAddress: ({ chain, walletCore, hexChainCode, publicKeys, publicKeyMldsa, chainPublicKeys, }: GetChainAddressInput) => string;
|
|
16
|
+
export declare const getChainAddress: ({ chain, walletCore, hexChainCode, publicKeys, publicKeyMldsa, chainPublicKeys, tonWalletVersion, }: GetChainAddressInput) => string;
|
|
14
17
|
export {};
|
|
15
18
|
//# sourceMappingURL=getChainAddress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getChainAddress.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/getChainAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"getChainAddress.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/getChainAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAIzE,OAAO,EAAE,UAAU,EAAE,MAAM,2CAA2C,CAAA;AAGtE,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,KAAK,CAAA;IACZ,UAAU,EAAE,UAAU,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IAChD,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;CACpC,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,eAAe,GAAI,qGAQ7B,oBAAoB,KAAG,MAczB,CAAA"}
|
|
@@ -4,7 +4,7 @@ import { deriveQbtcAddress } from '@vultisig/core-chain/publicKey/address/derive
|
|
|
4
4
|
import { getPublicKey } from '@vultisig/core-chain/publicKey/getPublicKey';
|
|
5
5
|
import { shouldBePresent } from '@vultisig/lib-utils/assert/shouldBePresent';
|
|
6
6
|
/** Derives the on-chain address for any chain, including MLDSA-based chains like QBTC. */
|
|
7
|
-
export const getChainAddress = ({ chain, walletCore, hexChainCode, publicKeys, publicKeyMldsa, chainPublicKeys, }) => {
|
|
7
|
+
export const getChainAddress = ({ chain, walletCore, hexChainCode, publicKeys, publicKeyMldsa, chainPublicKeys, tonWalletVersion, }) => {
|
|
8
8
|
if (chain === Chain.QBTC) {
|
|
9
9
|
return deriveQbtcAddress(shouldBePresent(publicKeyMldsa, 'MLDSA public key'));
|
|
10
10
|
}
|
|
@@ -15,6 +15,6 @@ export const getChainAddress = ({ chain, walletCore, hexChainCode, publicKeys, p
|
|
|
15
15
|
publicKeys,
|
|
16
16
|
chainPublicKeys,
|
|
17
17
|
});
|
|
18
|
-
return deriveAddress({ chain, publicKey, walletCore });
|
|
18
|
+
return deriveAddress({ chain, publicKey, walletCore, tonWalletVersion });
|
|
19
19
|
};
|
|
20
20
|
//# sourceMappingURL=getChainAddress.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getChainAddress.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/getChainAddress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"getChainAddress.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/publicKey/address/getChainAddress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAA;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAA;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAA;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAa5E,0FAA0F;AAC1F,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,GACK,EAAU,EAAE;IACjC,IAAI,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QACzB,OAAO,iBAAiB,CAAC,eAAe,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC,CAAA;IAC/E,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC;QAC7B,KAAK;QACL,UAAU;QACV,YAAY;QACZ,UAAU;QACV,eAAe;KAChB,CAAC,CAAA;IAEF,OAAO,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAA;AAC1E,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSwapKitQuote.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/swap/general/swapkit/api/getSwapKitQuote.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getSwapKitQuote.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/swap/general/swapkit/api/getSwapKitQuote.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AAGnE,OAAO,EAAE,gBAAgB,EAAiB,MAAM,oDAAoD,CAAA;AA4BpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAGzE,KAAK,KAAK,GAAG,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAAG;IACpD,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AA++BD,eAAO,MAAM,eAAe,GAAU,+CAMnC,KAAK,KAAG,OAAO,CAAC,gBAAgB,CAwElC,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { base64Decode } from '@bufbuild/protobuf/wire';
|
|
2
2
|
import { toChainAmount } from '@vultisig/core-chain/amount/toChainAmount';
|
|
3
3
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
4
|
+
import { areEqualTonAddresses, tonAddressToBounceable } from '@vultisig/core-chain/chains/ton/address';
|
|
4
5
|
import { chainFeeCoin } from '@vultisig/core-chain/coin/chainFeeCoin';
|
|
5
6
|
import { usdc } from '@vultisig/core-chain/coin/knownTokens';
|
|
6
7
|
import { assertSwapKitAddressReputation, assertSwapKitDestinationMatchesTarget, } from '@vultisig/core-chain/swap/general/knownAggregatorRouters';
|
|
@@ -9,6 +10,7 @@ import { isSwapKitSourceChain, } from '@vultisig/core-chain/swap/general/swapkit
|
|
|
9
10
|
import { SwapKitAmountBelowMinimumError, SwapKitFeeShapeError, SwapKitNoEligibleRoutesError, } from '@vultisig/core-chain/swap/general/swapkit/SwapKitErrors';
|
|
10
11
|
import { isSwapKitPairSupported, normalizeSwapKitProvider, resolveSwapKitChainMetadata, swapKitAllowedProviders, swapKitExcludedProviders, } from '@vultisig/core-chain/swap/general/swapkit/SwapKitProviders';
|
|
11
12
|
import { isOneOf } from '@vultisig/lib-utils/array/isOneOf';
|
|
13
|
+
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
12
14
|
import { withoutUndefinedFields } from '@vultisig/lib-utils/record/withoutUndefinedFields';
|
|
13
15
|
import { address as btcAddress, networks, Psbt } from 'bitcoinjs-lib';
|
|
14
16
|
const swapKitProviderQuoteAttempts = [
|
|
@@ -332,17 +334,97 @@ const toTransferAmount = (value, decimals) => {
|
|
|
332
334
|
}
|
|
333
335
|
return value.includes('.') ? toChainAmount(value, decimals) : BigInt(value);
|
|
334
336
|
};
|
|
337
|
+
const isTransferAmountValue = (value) => typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint';
|
|
335
338
|
const getTransferAmount = ({ depositAmount, tx }, amount, decimals) => {
|
|
336
339
|
if (depositAmount) {
|
|
337
340
|
return toChainAmount(depositAmount, decimals);
|
|
338
341
|
}
|
|
339
|
-
if (Array.isArray(tx) &&
|
|
340
|
-
isRecord(tx[0]) &&
|
|
341
|
-
(typeof tx[0].amount === 'string' || typeof tx[0].amount === 'number' || typeof tx[0].amount === 'bigint')) {
|
|
342
|
+
if (Array.isArray(tx) && isRecord(tx[0]) && isTransferAmountValue(tx[0].amount)) {
|
|
342
343
|
return toTransferAmount(tx[0].amount, decimals);
|
|
343
344
|
}
|
|
344
345
|
return amount;
|
|
345
346
|
};
|
|
347
|
+
/**
|
|
348
|
+
* The single transfer SwapKit describes in its `tx[]` array, or `undefined`
|
|
349
|
+
* when `tx` is any other shape — an EVM object, an opaque PSBT / PTB string, or
|
|
350
|
+
* absent because `disableBuildTx` was sent.
|
|
351
|
+
*
|
|
352
|
+
* More than one entry is rejected rather than ignored: only `tx[0]` is ever
|
|
353
|
+
* built, so a multi-transfer route would be signed as a partial deposit that
|
|
354
|
+
* under-funds the swap. The count is checked before the entry shape so a
|
|
355
|
+
* malformed trailing entry cannot slip a multi-transfer array past this guard.
|
|
356
|
+
*/
|
|
357
|
+
const getTransferTxEntry = (tx) => {
|
|
358
|
+
if (!Array.isArray(tx) || tx.length === 0) {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
if (tx.length > 1) {
|
|
362
|
+
throw new Error(`SwapKit transfer route returned ${tx.length} transfers; only the first would be signed, so the swap would be under-funded.`);
|
|
363
|
+
}
|
|
364
|
+
return isRecord(tx[0]) ? tx[0] : undefined;
|
|
365
|
+
};
|
|
366
|
+
/**
|
|
367
|
+
* The agreed TON deposit destination in its bounceable (`EQ…`) form.
|
|
368
|
+
*
|
|
369
|
+
* `assertTransferAgreement` compares TON spellings by account, so a route whose
|
|
370
|
+
* fields spell one account as `UQ…`, raw `0:hex` and `EQ…` passes — and the
|
|
371
|
+
* spelling that wins the precedence order is what the signer would otherwise
|
|
372
|
+
* read the bounce flag from. A deposit that goes out non-bounceable to a
|
|
373
|
+
* rejecting contract is absorbed instead of refunded, so the agreed account is
|
|
374
|
+
* re-spelled bounceable here, whichever field it came from. A string that is
|
|
375
|
+
* not a TON address at all cannot be a deposit destination and is refused.
|
|
376
|
+
*/
|
|
377
|
+
const toCanonicalTonDeposit = (destination) => {
|
|
378
|
+
const canonical = attempt(() => tonAddressToBounceable(destination));
|
|
379
|
+
if ('error' in canonical) {
|
|
380
|
+
throw new Error(`SwapKit transfer route returned an invalid TON deposit address: ${destination}`);
|
|
381
|
+
}
|
|
382
|
+
return canonical.data;
|
|
383
|
+
};
|
|
384
|
+
const areEqualTransferAddresses = (left, right, chain) => chain === Chain.Ton ? areEqualTonAddresses(left, right) : left === right;
|
|
385
|
+
/**
|
|
386
|
+
* Fail closed when the `/v3/swap` response disagrees with itself about where
|
|
387
|
+
* the deposit goes or how large it is.
|
|
388
|
+
*
|
|
389
|
+
* `targetAddress`, `depositAddress` and `tx[]` are independent fields carrying
|
|
390
|
+
* the same fact, and the resolvers above take the first one that is present and
|
|
391
|
+
* never look at the rest. So a response whose halves diverge — a provider bug,
|
|
392
|
+
* an API change, a tampered payload — signs whichever field happens to win the
|
|
393
|
+
* precedence order while the others name a different recipient or size, and
|
|
394
|
+
* nothing downstream can tell. Neither field is authoritative enough to pick a
|
|
395
|
+
* winner from, so a divergence is refused instead of resolved.
|
|
396
|
+
*
|
|
397
|
+
* Addresses are compared per chain because TON spells one account as `EQ…`,
|
|
398
|
+
* `UQ…` or raw `workchain:hex` — comparing those as strings would reject
|
|
399
|
+
* healthy routes.
|
|
400
|
+
*/
|
|
401
|
+
const assertTransferAgreement = (response, chain, decimals) => {
|
|
402
|
+
const entry = getTransferTxEntry(response.tx);
|
|
403
|
+
const destinations = [
|
|
404
|
+
{ field: 'targetAddress', value: response.targetAddress },
|
|
405
|
+
{ field: 'depositAddress', value: response.depositAddress },
|
|
406
|
+
{ field: 'tx[0].address', value: typeof entry?.address === 'string' ? entry.address : undefined },
|
|
407
|
+
].flatMap(({ field, value }) => (value?.trim() ? [{ field, value: value.trim() }] : []));
|
|
408
|
+
const [primaryDestination, ...otherDestinations] = destinations;
|
|
409
|
+
if (primaryDestination) {
|
|
410
|
+
const divergent = otherDestinations.find(({ value }) => !areEqualTransferAddresses(value, primaryDestination.value, chain));
|
|
411
|
+
if (divergent) {
|
|
412
|
+
throw new Error(`SwapKit transfer route disagrees with itself about the destination: ` +
|
|
413
|
+
`${primaryDestination.field} is ${primaryDestination.value} but ${divergent.field} is ${divergent.value}.`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const txAmountValue = entry && isTransferAmountValue(entry.amount) ? entry.amount : undefined;
|
|
417
|
+
if (txAmountValue === undefined || !response.depositAmount) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const txAmount = toTransferAmount(txAmountValue, decimals);
|
|
421
|
+
const depositAmount = toChainAmount(response.depositAmount, decimals);
|
|
422
|
+
if (txAmount !== depositAmount) {
|
|
423
|
+
throw new Error(`SwapKit transfer route disagrees with itself about the amount: ` +
|
|
424
|
+
`depositAmount is ${response.depositAmount} (${depositAmount} base units) ` +
|
|
425
|
+
`but tx[0].amount is ${txAmountValue} (${txAmount} base units).`);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
346
428
|
const shouldUseTransferTx = (chain) => isOneOf(chain, swapKitTransferSourceChains);
|
|
347
429
|
// Transfer-arm chains that still need SwapKit to BUILD the transaction, so
|
|
348
430
|
// `/v3/swap` must not be sent `disableBuildTx`. Bitcoin gets a PSBT and Sui a
|
|
@@ -397,10 +479,12 @@ const getBitcoinPsbtDestinationAmount = ({ txPayload, senderAddress, targetAddre
|
|
|
397
479
|
}
|
|
398
480
|
};
|
|
399
481
|
const buildTransferTx = (response, from, amount) => {
|
|
400
|
-
|
|
401
|
-
|
|
482
|
+
assertTransferAgreement(response, from.chain, from.decimals);
|
|
483
|
+
const agreedDestination = getTransferTargetAddress(response);
|
|
484
|
+
if (!agreedDestination) {
|
|
402
485
|
throw new Error('SwapKit transfer route did not return a target address.');
|
|
403
486
|
}
|
|
487
|
+
const to = from.chain === Chain.Ton ? toCanonicalTonDeposit(agreedDestination) : agreedDestination;
|
|
404
488
|
// SwapKit renames base64 tx types on the wire without versioning — `SOLANA`
|
|
405
489
|
// became `SERIALIZED_BASE64` and `CARDANO` became `CBOR` mid-flight (iOS
|
|
406
490
|
// accepts both spellings in `SwapKitSwapResponse.decodeTx`). A Sui route's
|