@vultisig/core-chain 5.1.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 +28 -0
- 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/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/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/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 +16 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @vultisig/core-chain
|
|
2
2
|
|
|
3
|
+
## 5.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#2306](https://github.com/vultisig/vultisig-sdk/pull/2306) [`a5def09`](https://github.com/vultisig/vultisig-sdk/commit/a5def098e06cf7269174eb6840dc516d78ec55f9) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - feat(ton): explain TON failures in plain language — seqno replay, expired deadline, fees, and the rest
|
|
8
|
+
|
|
9
|
+
A TON send that fails today comes back as an opaque `exitcode=133` in a toncenter rejection, or as a bare `error` status with nothing attached. Those two codes — 133 (W5) / 33 (v4) for a replayed seqno and 136 / 36 for an expired `valid_until`, which is almost always a device clock that drifted — dominate TON support load, and the fix is different for each.
|
|
10
|
+
|
|
11
|
+
`@vultisig/core-chain/chains/ton/failure` maps a failure to a `TonTxFailure`: a stable `reason` (`seqno-mismatch`, `expired`, `invalid-signature`, `wallet-id-mismatch`, `insufficient-funds`, `out-of-gas`, `invalid-destination`, `not-enough-jettons`, `jetton-unauthorized`, `action-failed`, `action-partially-failed`, `aborted`, `contract-rejected`), the phase it came from, the raw exit code, and an English `message` that says what happened and what to do ("make sure your device's date and time are set automatically, then send it again"; "keep about 0.05 TON spare for fees"). Compute-phase codes cover wallet v3/v4 and W5 alike, the TVM out-of-gas codes and the standard jetton wallet's 705/706 (707 and 709 stay generic: the reference contract reuses each for two unrelated checks); action-phase codes distinguish 36 (invalid destination) from the wallet's 36 (expired), and read 37 as not enough TON. Action code 40 stays generic on purpose: it reads "not enough funds, the message is too large, or its Merkle depth is too big", so it is a funding failure only when the node's own `no_funds` flag backs it, and any other unnamed code is treated the same way.
|
|
12
|
+
|
|
13
|
+
A generic action-phase failure only claims "nothing was sent" when the node reports `msgs_created: 0`. Every Vultisig TON send goes out with `IGNORE_ERRORS`, under which a failing action is skipped and the rest still leave, so a batch can lose one transfer and deliver the others — telling that user to retry is how a transfer goes out twice. Without that evidence the failure is `action-partially-failed`, whose message says at least one transfer did not happen, that others may have, and to check the transaction history before sending again.
|
|
14
|
+
|
|
15
|
+
`TxStatusResult` gains an optional `failure?: TxFailureInfo` (`reason`, `message`, `exitCode?`, `phase?`), which the TON status resolver now fills for every `error`. `broadcastTonTx` classifies a wallet-contract refusal at broadcast time: the failed result's `cause` is a `TonBroadcastRejectedError` carrying the same `failure`, its `message` is the human explanation, the original toncenter error stays in `cause`, and the refusal is marked non-retryable — resending the same bytes can only be refused again. A seqno refusal whose message is already on chain (a co-signer broadcast first) is still accepted through the existing hash verification. The types, `getTonTxFailure`, `parseTonBroadcastRejection` and `TonBroadcastRejectedError` are re-exported from `@vultisig/sdk`, including its React Native entry — RN broadcasts TON itself and its `broadcastTonTx` rejects with toncenter's raw `exitcode=<n>` text.
|
|
16
|
+
|
|
17
|
+
- [#2299](https://github.com/vultisig/vultisig-sdk/pull/2299) [`bcca32c`](https://github.com/vultisig/vultisig-sdk/commit/bcca32c885066e2bf224aa37d6666c68a3684956) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - feat(ton): W5 (wallet v5r1) support as an explicit per-account opt-in
|
|
18
|
+
|
|
19
|
+
Every Vultisig TON account has been hard-pinned to the V4R2 wallet contract. W5 is the default for new wallets in Tonkeeper and Telegram Wallet and is the gateway to what users now expect from TON — up to 255 messages per request instead of 4, lower fees, and relayer-paid ("gasless") transactions. WalletCore has supported it for a while; nothing here used it.
|
|
20
|
+
|
|
21
|
+
A W5 wallet is a _different address_ for the same key, with its own balance, so this is not a switch: V4R2 stays the default everywhere and W5 is selected per account.
|
|
22
|
+
|
|
23
|
+
- `@vultisig/core-chain/chains/ton/wallet` (new): `TonWalletVersion` (`'v4r2' | 'v5r1'`), `deriveTonAddress` for either contract, `resolveTonWalletVersion` to tell which contract an address is for a key, the W5 mainnet wallet id, and the per-contract message limits.
|
|
24
|
+
- `vault.setTonWalletVersion('v5r1')` selects which of the key's two TON accounts the vault acts on: `send`, balances, swaps, fee estimation and every other address lookup follow it, so one selected account is used consistently. `vault.address(chain, { tonWalletVersion })` — like `deriveAddress` / `getChainAddress` / `deriveAddressFromKeys` — names a contract for a single lookup without changing the selection, so a client can show both accounts side by side for a migration flow.
|
|
25
|
+
- Balance cache keys name a chain and an asset, not an account, so switching between the two accounts drops the balance scope and any fetch already in flight for the old account is neither cached nor announced: it still answers its own caller, but `balanceUpdated` carries no account identity, so emitting it after a switch would credit the old account's balance to the new one.
|
|
26
|
+
- The keysign signing-input resolver derives the contract from the sender address — the payload has no wallet-version field, and every co-signer reaches the same answer from the shared vault key — and refuses an address that is neither of the key's wallets rather than assuming V4R2. W5 requests carry `IGNORE_ACTION_PHASE_ERRORS`, which the W5 code requires of every external action (its replay protection) and WalletCore enforces; the TON status resolver's action-phase check covers the blindness that flag would otherwise cause. Message counts are capped per contract.
|
|
27
|
+
- The RN-safe builders (`buildTonSendTx`, `buildTonJettonTransferTx`, `buildTonTxFromSigningPayload`, `deriveTonAddress`, `prepareJettonTransferTxFromKeys`) take `walletVersion`; W5 uses the `signed_external` request layout with the signature appended, byte-identical to WalletCore. New `buildV5R1Wallet` / `TON_V5R1_WALLET_ID` alongside the V4R2 helpers.
|
|
28
|
+
|
|
29
|
+
Golden vectors (`testdata/cross-encoder-golden/ton-w5-*.json`) pin the W5 pre-images and are verified against real WalletCore, including the full signed external message. Client-side migration UI (show both accounts, move funds, reconnect dApps) is separate work per platform.
|
|
30
|
+
|
|
3
31
|
## 5.1.0
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a TON transaction did not move funds, in terms a user can act on. The
|
|
3
|
+
* wallet contract's own checks (`seqno-mismatch`, `expired`, `invalid-signature`,
|
|
4
|
+
* `wallet-id-mismatch`) fire in the compute phase of the sender's wallet; the
|
|
5
|
+
* money-related ones fire when the wallet tries to emit the transfer (action
|
|
6
|
+
* phase) or in the jetton wallet's compute phase.
|
|
7
|
+
*/
|
|
8
|
+
export declare const tonTxFailureReasons: readonly ["seqno-mismatch", "expired", "invalid-signature", "wallet-id-mismatch", "insufficient-funds", "out-of-gas", "invalid-destination", "not-enough-jettons", "jetton-unauthorized", "action-failed", "action-partially-failed", "aborted", "contract-rejected"];
|
|
9
|
+
export type TonTxFailureReason = (typeof tonTxFailureReasons)[number];
|
|
10
|
+
/** Which phase of the TON transaction produced the code: TVM execution or emitting the outgoing messages. */
|
|
11
|
+
export type TonTxPhase = 'compute' | 'action';
|
|
12
|
+
export type TonTxFailure = {
|
|
13
|
+
reason: TonTxFailureReason;
|
|
14
|
+
phase: TonTxPhase;
|
|
15
|
+
exitCode?: number;
|
|
16
|
+
/** Plain-language explanation with the remedy, in English. */
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
/** Classifies a compute-phase exit code (0 and 1 are success and yield `undefined`). */
|
|
20
|
+
export declare const getTonComputeFailure: (exitCode: number | undefined) => TonTxFailure | undefined;
|
|
21
|
+
type TonActionPhaseOutcome = {
|
|
22
|
+
success?: boolean;
|
|
23
|
+
no_funds?: boolean;
|
|
24
|
+
result_code?: number;
|
|
25
|
+
skipped_actions?: number;
|
|
26
|
+
/** Outgoing messages the phase actually produced, when the node reports it. */
|
|
27
|
+
msgs_created?: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Classifies a failed action phase. A result code the table names wins; an
|
|
31
|
+
* unnamed one is read as a funding failure only when `no_funds` backs it, and
|
|
32
|
+
* otherwise stays generic with the code attached. `no_funds` without any code
|
|
33
|
+
* still means the transfer could not be paid for, and a skipped or unsuccessful
|
|
34
|
+
* action with neither is generic — worded by `genericActionReason`, which will not
|
|
35
|
+
* claim nothing was sent unless the node says so.
|
|
36
|
+
*/
|
|
37
|
+
export declare const getTonActionFailure: (action: TonActionPhaseOutcome | undefined) => TonTxFailure | undefined;
|
|
38
|
+
type TonTransactionOutcome = {
|
|
39
|
+
aborted?: boolean;
|
|
40
|
+
compute_ph?: {
|
|
41
|
+
exit_code?: number;
|
|
42
|
+
};
|
|
43
|
+
action?: TonActionPhaseOutcome;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Explains why an indexed TON transaction failed, or `undefined` when it did
|
|
47
|
+
* not. The compute phase is consulted first because it carries the specific
|
|
48
|
+
* exit code; an aborted transaction with no readable phase is reported as such.
|
|
49
|
+
*/
|
|
50
|
+
export declare const getTonTxFailure: (description: TonTransactionOutcome) => TonTxFailure | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Reads the wallet contract's exit code out of a toncenter `sendBoc` rejection
|
|
53
|
+
* ("… inbound external message rejected by transaction …: exitcode=133, steps=49,
|
|
54
|
+
* gas_used=0 …"). The message never reached the chain, so the code is always the
|
|
55
|
+
* sender's wallet refusing it in its compute phase. Returns `undefined` for
|
|
56
|
+
* transport errors and any other rejection shape.
|
|
57
|
+
*/
|
|
58
|
+
export declare const parseTonBroadcastRejection: (error: unknown) => TonTxFailure | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* A TON broadcast the sender's wallet contract refused, with the refusal
|
|
61
|
+
* classified. `message` is the human-readable explanation so any consumer that
|
|
62
|
+
* only prints `error.message` already shows the right remedy; the original
|
|
63
|
+
* toncenter error stays in `cause`.
|
|
64
|
+
*/
|
|
65
|
+
export declare class TonBroadcastRejectedError extends Error {
|
|
66
|
+
readonly failure: TonTxFailure;
|
|
67
|
+
constructor(failure: TonTxFailure, cause: unknown);
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=failure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/failure.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,uQActB,CAAA;AAEV,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAErE,6GAA6G;AAC7G,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE7C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,kBAAkB,CAAA;IAC1B,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAsFD,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,GAAI,UAAU,MAAM,GAAG,SAAS,KAAG,YAAY,GAAG,SAIlF,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAeD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,qBAAqB,GAAG,SAAS,KAAG,YAAY,GAAG,SAkB9F,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACnC,MAAM,CAAC,EAAE,qBAAqB,CAAA;CAC/B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,aAAa,qBAAqB,KAAG,YAAY,GAAG,SAGJ,CAAA;AAIhF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,YAAY,GAAG,SAK1E,CAAA;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;aAEhC,OAAO,EAAE,YAAY;gBAArB,OAAO,EAAE,YAAY,EACrC,KAAK,EAAE,OAAO;CAKjB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { extractErrorMsg } from '@vultisig/lib-utils/error/extractErrorMsg';
|
|
2
|
+
/**
|
|
3
|
+
* Why a TON transaction did not move funds, in terms a user can act on. The
|
|
4
|
+
* wallet contract's own checks (`seqno-mismatch`, `expired`, `invalid-signature`,
|
|
5
|
+
* `wallet-id-mismatch`) fire in the compute phase of the sender's wallet; the
|
|
6
|
+
* money-related ones fire when the wallet tries to emit the transfer (action
|
|
7
|
+
* phase) or in the jetton wallet's compute phase.
|
|
8
|
+
*/
|
|
9
|
+
export const tonTxFailureReasons = [
|
|
10
|
+
'seqno-mismatch',
|
|
11
|
+
'expired',
|
|
12
|
+
'invalid-signature',
|
|
13
|
+
'wallet-id-mismatch',
|
|
14
|
+
'insufficient-funds',
|
|
15
|
+
'out-of-gas',
|
|
16
|
+
'invalid-destination',
|
|
17
|
+
'not-enough-jettons',
|
|
18
|
+
'jetton-unauthorized',
|
|
19
|
+
'action-failed',
|
|
20
|
+
'action-partially-failed',
|
|
21
|
+
'aborted',
|
|
22
|
+
'contract-rejected',
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Compute-phase exit codes. The sender's wallet contract throws the first block
|
|
26
|
+
* from `recv_external`: wallet v3/v4 use 33–36, W5 uses 133–136 for the same
|
|
27
|
+
* checks. 13 / -14 are the TVM's out-of-gas codes. 705 and 706 come from the
|
|
28
|
+
* standard jetton wallet (TEP-74) and mean the same thing on a transfer and on
|
|
29
|
+
* a burn; its 707 and 709 are deliberately absent because the reference
|
|
30
|
+
* contract reuses each for two unrelated checks (707: unauthorized incoming
|
|
31
|
+
* transfer, or too little TON on a burn; 709: too little TON on a transfer, or
|
|
32
|
+
* an unexpected bounced op), and the code alone cannot tell which. Everything
|
|
33
|
+
* else is a contract-specific revert we can only report by number.
|
|
34
|
+
*/
|
|
35
|
+
const computeExitCodeReasons = {
|
|
36
|
+
33: 'seqno-mismatch',
|
|
37
|
+
133: 'seqno-mismatch',
|
|
38
|
+
34: 'wallet-id-mismatch',
|
|
39
|
+
134: 'wallet-id-mismatch',
|
|
40
|
+
35: 'invalid-signature',
|
|
41
|
+
135: 'invalid-signature',
|
|
42
|
+
36: 'expired',
|
|
43
|
+
136: 'expired',
|
|
44
|
+
13: 'out-of-gas',
|
|
45
|
+
[-14]: 'out-of-gas',
|
|
46
|
+
705: 'jetton-unauthorized',
|
|
47
|
+
706: 'not-enough-jettons',
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Action-phase result codes that mean one thing. 36 here is an invalid destination,
|
|
51
|
+
* not the wallet's `expired` (36), which can only come from the compute phase. 37 is
|
|
52
|
+
* "Not enough GRAMs" and says so on its own.
|
|
53
|
+
*
|
|
54
|
+
* 40 is deliberately absent. It reads "Cannot process a message — not enough funds,
|
|
55
|
+
* the message is too large, or its Merkle depth is too big", so naming it a funding
|
|
56
|
+
* failure would send a user to top up their balance when the payload is what has to
|
|
57
|
+
* change. Codes like it fall through to `no_funds` below, the only authoritative
|
|
58
|
+
* funding signal in the phase.
|
|
59
|
+
*/
|
|
60
|
+
const actionResultCodeReasons = {
|
|
61
|
+
36: 'invalid-destination',
|
|
62
|
+
37: 'insufficient-funds',
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Human-readable explanations. Each says what happened and what to do; the
|
|
66
|
+
* remedy matters more than the code, because the two failures that dominate
|
|
67
|
+
* TON support — a replayed seqno and an expired `valid_until` — both look like
|
|
68
|
+
* "the network rejected it" and have opposite fixes.
|
|
69
|
+
*/
|
|
70
|
+
const failureMessages = {
|
|
71
|
+
'seqno-mismatch': 'Another transaction from this wallet was processed first, so the network rejected this one as out of order. Check your history: if this transfer is not there, send it again.',
|
|
72
|
+
expired: "The transaction's time window closed before the network processed it. Make sure your device's date and time are set automatically, then send it again.",
|
|
73
|
+
'invalid-signature': 'The wallet contract rejected the signature. Sign the transaction again; if it keeps failing, the wallet contract at this address does not match this vault.',
|
|
74
|
+
'wallet-id-mismatch': 'The transaction was built for a different wallet contract version than the one deployed at this address.',
|
|
75
|
+
'insufficient-funds': 'Not enough TON to cover the amount plus network fees. Keep about 0.05 TON spare for fees and try again.',
|
|
76
|
+
'out-of-gas': 'The transaction ran out of gas before it could finish. Attach more TON to the transfer and try again.',
|
|
77
|
+
'invalid-destination': 'The destination address is not valid on TON. Check the address and try again.',
|
|
78
|
+
'not-enough-jettons': 'This wallet does not hold enough of the token to send that amount.',
|
|
79
|
+
'jetton-unauthorized': 'The token contract refused the transfer because this wallet is not allowed to move these tokens.',
|
|
80
|
+
'action-failed': 'The wallet accepted the transaction but could not carry out the transfer, so nothing was sent. The network fee was still charged. Check the transaction and try again.',
|
|
81
|
+
'action-partially-failed': 'The wallet could not carry out at least one transfer in this transaction, and others in it may have gone through. The network fee was still charged. Check your transaction history before sending again.',
|
|
82
|
+
aborted: 'The network aborted this transaction before it could carry out the transfer.',
|
|
83
|
+
'contract-rejected': 'The contract rejected the transaction.',
|
|
84
|
+
};
|
|
85
|
+
const describe = (reason, exitCode) => reason === 'contract-rejected' && exitCode !== undefined
|
|
86
|
+
? `The contract rejected the transaction (exit code ${exitCode}).`
|
|
87
|
+
: failureMessages[reason];
|
|
88
|
+
const makeFailure = (reason, phase, exitCode) => ({
|
|
89
|
+
reason,
|
|
90
|
+
phase,
|
|
91
|
+
...(exitCode === undefined ? {} : { exitCode }),
|
|
92
|
+
message: describe(reason, exitCode),
|
|
93
|
+
});
|
|
94
|
+
/** Classifies a compute-phase exit code (0 and 1 are success and yield `undefined`). */
|
|
95
|
+
export const getTonComputeFailure = (exitCode) => {
|
|
96
|
+
if (exitCode === undefined || exitCode === 0 || exitCode === 1)
|
|
97
|
+
return undefined;
|
|
98
|
+
return makeFailure(computeExitCodeReasons[exitCode] ?? 'contract-rejected', 'compute', exitCode);
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Which generic explanation a failed action phase gets.
|
|
102
|
+
*
|
|
103
|
+
* Under `IGNORE_ERRORS` — the mode every Vultisig TON send uses — a failing action
|
|
104
|
+
* is skipped and the remaining ones still go out, so a batch can lose one transfer
|
|
105
|
+
* and deliver the rest. Telling that user nothing was sent and to try again is how a
|
|
106
|
+
* duplicate transfer happens, so only the node's own `msgs_created: 0` earns the
|
|
107
|
+
* "nothing was sent" wording. A node that reports nothing proves nothing either way
|
|
108
|
+
* and gets the neutral explanation, which reads correctly for both outcomes.
|
|
109
|
+
*/
|
|
110
|
+
const genericActionReason = ({ msgs_created }) => msgs_created === 0 ? 'action-failed' : 'action-partially-failed';
|
|
111
|
+
/**
|
|
112
|
+
* Classifies a failed action phase. A result code the table names wins; an
|
|
113
|
+
* unnamed one is read as a funding failure only when `no_funds` backs it, and
|
|
114
|
+
* otherwise stays generic with the code attached. `no_funds` without any code
|
|
115
|
+
* still means the transfer could not be paid for, and a skipped or unsuccessful
|
|
116
|
+
* action with neither is generic — worded by `genericActionReason`, which will not
|
|
117
|
+
* claim nothing was sent unless the node says so.
|
|
118
|
+
*/
|
|
119
|
+
export const getTonActionFailure = (action) => {
|
|
120
|
+
if (!action)
|
|
121
|
+
return undefined;
|
|
122
|
+
const { success, no_funds, result_code, skipped_actions } = action;
|
|
123
|
+
if (result_code !== undefined && result_code !== 0) {
|
|
124
|
+
// A code the table does not name is a funding failure only when the node says so.
|
|
125
|
+
const reason = actionResultCodeReasons[result_code] ?? (no_funds === true ? 'insufficient-funds' : genericActionReason(action));
|
|
126
|
+
return makeFailure(reason, 'action', result_code);
|
|
127
|
+
}
|
|
128
|
+
if (no_funds === true)
|
|
129
|
+
return makeFailure('insufficient-funds', 'action');
|
|
130
|
+
if (success === false || (skipped_actions ?? 0) > 0)
|
|
131
|
+
return makeFailure(genericActionReason(action), 'action');
|
|
132
|
+
return undefined;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Explains why an indexed TON transaction failed, or `undefined` when it did
|
|
136
|
+
* not. The compute phase is consulted first because it carries the specific
|
|
137
|
+
* exit code; an aborted transaction with no readable phase is reported as such.
|
|
138
|
+
*/
|
|
139
|
+
export const getTonTxFailure = (description) => getTonComputeFailure(description.compute_ph?.exit_code) ??
|
|
140
|
+
getTonActionFailure(description.action) ??
|
|
141
|
+
(description.aborted === true ? makeFailure('aborted', 'compute') : undefined);
|
|
142
|
+
const rejectionExitCodePattern = /exitcode=(-?\d+)/i;
|
|
143
|
+
/**
|
|
144
|
+
* Reads the wallet contract's exit code out of a toncenter `sendBoc` rejection
|
|
145
|
+
* ("… inbound external message rejected by transaction …: exitcode=133, steps=49,
|
|
146
|
+
* gas_used=0 …"). The message never reached the chain, so the code is always the
|
|
147
|
+
* sender's wallet refusing it in its compute phase. Returns `undefined` for
|
|
148
|
+
* transport errors and any other rejection shape.
|
|
149
|
+
*/
|
|
150
|
+
export const parseTonBroadcastRejection = (error) => {
|
|
151
|
+
const match = rejectionExitCodePattern.exec(String(extractErrorMsg(error)));
|
|
152
|
+
if (!match)
|
|
153
|
+
return undefined;
|
|
154
|
+
return getTonComputeFailure(Number(match[1]));
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* A TON broadcast the sender's wallet contract refused, with the refusal
|
|
158
|
+
* classified. `message` is the human-readable explanation so any consumer that
|
|
159
|
+
* only prints `error.message` already shows the right remedy; the original
|
|
160
|
+
* toncenter error stays in `cause`.
|
|
161
|
+
*/
|
|
162
|
+
export class TonBroadcastRejectedError extends Error {
|
|
163
|
+
failure;
|
|
164
|
+
constructor(failure, cause) {
|
|
165
|
+
super(failure.message, { cause });
|
|
166
|
+
this.failure = failure;
|
|
167
|
+
this.name = 'TonBroadcastRejectedError';
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=failure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/failure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PublicKey, WalletCore } from '@trustwallet/wallet-core/dist/src/wallet-core';
|
|
2
|
+
import { tonV5R1WalletId } from '@vultisig/core-chain/chains/ton/walletV5R1';
|
|
3
|
+
/**
|
|
4
|
+
* The wallet contracts a Vultisig TON account can live in. The same Ed25519
|
|
5
|
+
* key yields a different address under each, so they are different accounts.
|
|
6
|
+
*/
|
|
7
|
+
export declare const tonWalletVersions: readonly ["v4r2", "v5r1"];
|
|
8
|
+
export type TonWalletVersion = (typeof tonWalletVersions)[number];
|
|
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 declare const defaultTonWalletVersion: TonWalletVersion;
|
|
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 declare const tonMaxMessagesPerRequest: Record<TonWalletVersion, number>;
|
|
21
|
+
type DeriveTonAddressInput = {
|
|
22
|
+
publicKey: PublicKey;
|
|
23
|
+
walletCore: WalletCore;
|
|
24
|
+
version: TonWalletVersion;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The user-friendly, non-bounceable (`UQ…`) address of this key's wallet
|
|
28
|
+
* under the given contract. V4R2 is WalletCore's own TON derivation; W5 is the
|
|
29
|
+
* hash of the StateInit the contract is deployed from, built with `@ton/core`
|
|
30
|
+
* from the key bytes alone — no WalletCore feature beyond the public key, so it
|
|
31
|
+
* also works on React Native, whose native bridge exposes no `TONWallet`.
|
|
32
|
+
*/
|
|
33
|
+
export declare const deriveTonAddress: ({ publicKey, walletCore, version }: DeriveTonAddressInput) => string;
|
|
34
|
+
type ResolveTonWalletVersionInput = {
|
|
35
|
+
address: string;
|
|
36
|
+
publicKey: PublicKey;
|
|
37
|
+
walletCore: WalletCore;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Which wallet contract an address is, for this key.
|
|
41
|
+
*
|
|
42
|
+
* The keysign payload carries no wallet-version field, so the sender address
|
|
43
|
+
* is the contract's identity: every co-signer derives both candidate addresses
|
|
44
|
+
* from the shared vault key and matches. An address that is neither is refused
|
|
45
|
+
* rather than assumed V4R2 — signing a V4R2 request for a wallet that is not
|
|
46
|
+
* one would either be rejected on chain or, worse, accepted by a contract we
|
|
47
|
+
* never meant to drive.
|
|
48
|
+
*/
|
|
49
|
+
export declare const resolveTonWalletVersion: ({ address, publicKey, walletCore }: ResolveTonWalletVersionInput) => "v4r2" | "v5r1";
|
|
50
|
+
//# sourceMappingURL=wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/ton/wallet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAqB,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAG/F;;;GAGG;AACH,eAAO,MAAM,iBAAiB,2BAA4B,CAAA;AAE1D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,gBAAyB,CAAA;AAE/D,OAAO,EAAE,eAAe,EAAE,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAA0B,CAAA;AAEhG,KAAK,qBAAqB,GAAG;IAC3B,SAAS,EAAE,SAAS,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,gBAAgB,CAAA;CAC1B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,oCAAoC,qBAAqB,KAAG,MASzF,CAAA;AAEJ,KAAK,4BAA4B,GAAG;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,SAAS,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAI,oCAAoC,4BAA4B,oBAcvG,CAAA"}
|
|
@@ -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,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":"ton.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"ton.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAOvD,OAAO,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AAGhH,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,CAmC9D,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseTonBroadcastRejection, TonBroadcastRejectedError } from '@vultisig/core-chain/chains/ton/failure';
|
|
1
2
|
import { rootApiUrl } from '@vultisig/core-config';
|
|
2
3
|
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
3
4
|
import { isInError } from '@vultisig/lib-utils/error/isInError';
|
|
@@ -24,6 +25,13 @@ export const broadcastTonTx = async ({ chain, tx }) => {
|
|
|
24
25
|
return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
|
|
25
26
|
}
|
|
26
27
|
catch (cause) {
|
|
28
|
+
// The wallet contract refusing the message (seqno replay, expired
|
|
29
|
+
// valid_until, bad signature …) is final: re-sending the same bytes gets
|
|
30
|
+
// the same refusal, and the user needs the reason, not a retry.
|
|
31
|
+
const failure = parseTonBroadcastRejection(cause);
|
|
32
|
+
if (failure) {
|
|
33
|
+
return broadcastFailed(new TonBroadcastRejectedError(failure, cause), false);
|
|
34
|
+
}
|
|
27
35
|
return broadcastFailed(cause, responseMissingHash ? false : isRetryableBroadcastCause(error));
|
|
28
36
|
}
|
|
29
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ton.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAuB,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAChH,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAwC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACzF,MAAM,GAAG,GAAG,GAAG,UAAU,2BAA2B,CAAA;IAEpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,QAAQ,CAAiC,GAAG,EAAE;QAC5C,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,EAAE;KAC1B,CAAC,CACH,CAAA;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAA;IACtC,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,CAAA;IACrD,MAAM,KAAK,GAAG,mBAAmB;QAC/B,CAAC,CAAC,IAAI,KAAK,CAAC,4DAA4D,CAAC;QACzE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;IAChB,IAAI,SAAS,CAAC,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,CAAC,EAAE,CAAC;QACjE,OAAO,iBAAiB,EAAE,CAAA;IAC5B,CAAC;IAED,IAAI,CAAC;QACH,OAAO,iBAAiB,CAAC,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAC7E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/F,CAAC;AACH,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ton.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AAC/G,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAuB,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAChH,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAwC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACzF,MAAM,GAAG,GAAG,GAAG,UAAU,2BAA2B,CAAA;IAEpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,QAAQ,CAAiC,GAAG,EAAE;QAC5C,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,EAAE;KAC1B,CAAC,CACH,CAAA;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAA;IACtC,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,CAAA;IACrD,MAAM,KAAK,GAAG,mBAAmB;QAC/B,CAAC,CAAC,IAAI,KAAK,CAAC,4DAA4D,CAAC;QACzE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;IAChB,IAAI,SAAS,CAAC,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,CAAC,EAAE,CAAC;QACjE,OAAO,iBAAiB,EAAE,CAAA;IAC5B,CAAC;IAED,IAAI,CAAC;QACH,OAAO,iBAAiB,CAAC,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAC7E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kEAAkE;QAClE,yEAAyE;QACzE,gEAAgE;QAChE,MAAM,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAA;QACjD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,eAAe,CAAC,IAAI,yBAAyB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;QAC9E,CAAC;QAED,OAAO,eAAe,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/F,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TxReceiptInfo, TxStatusInput } from './resolver.js';
|
|
1
|
+
import { TxFailureInfo, TxReceiptInfo, TxStatusInput } from './resolver.js';
|
|
2
2
|
export declare const getTxStatus: (input: TxStatusInput) => Promise<import("./resolver.js").TxStatusResult>;
|
|
3
|
-
export type { TxReceiptInfo, TxStatusInput };
|
|
3
|
+
export type { TxFailureInfo, TxReceiptInfo, TxStatusInput };
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/tx/status/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/tx/status/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,YAAY,CAAA;AA6B1F,eAAO,MAAM,WAAW,GAAI,OAAO,aAAa,iDAO/C,CAAA;AAED,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -14,10 +14,25 @@ export type TxReceiptInfo = {
|
|
|
14
14
|
/** Present only for a multi-purpose-token delivery. */
|
|
15
15
|
deliveredMptIssuanceId?: string;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Why a transaction ended in `error`, when the chain exposes a reason. `reason`
|
|
19
|
+
* is a stable, chain-specific identifier (see `TonTxFailureReason`) a UI can
|
|
20
|
+
* translate; `message` is the English explanation with the remedy for consumers
|
|
21
|
+
* that only print text; `exitCode` is the raw contract/VM code when there is
|
|
22
|
+
* one, and `phase` names the execution phase that produced it (TON: `compute`
|
|
23
|
+
* or `action` — the same number means different things in each).
|
|
24
|
+
*/
|
|
25
|
+
export type TxFailureInfo = {
|
|
26
|
+
reason: string;
|
|
27
|
+
message: string;
|
|
28
|
+
exitCode?: number;
|
|
29
|
+
phase?: string;
|
|
30
|
+
};
|
|
17
31
|
export type TxStatusResult = {
|
|
18
32
|
status: TxStatus;
|
|
19
33
|
isKnown?: boolean;
|
|
20
34
|
receipt?: TxReceiptInfo;
|
|
35
|
+
failure?: TxFailureInfo;
|
|
21
36
|
};
|
|
22
37
|
export type TxStatusInput<T extends Chain = Chain> = {
|
|
23
38
|
chain: T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/tx/status/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAOnC,KAAK,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAA;AAEzE,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,0GAA0G;IAC1G,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,uDAAuD;IACvD,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,QAAQ,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,IAAI;IACnD,KAAK,EAAE,CAAC,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/tx/status/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAOnC,KAAK,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAA;AAEzE,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,0GAA0G;IAC1G,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,uDAAuD;IACvD,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,QAAQ,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,IAAI;IACnD,KAAK,EAAE,CAAC,CAAA;IACR,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAA"}
|
|
@@ -4,7 +4,11 @@ import { TxStatusResolver } from '../resolver.js';
|
|
|
4
4
|
* Resolves a TON transaction by the hash of the external message that carried it.
|
|
5
5
|
* Success requires the transaction to be un-aborted *and* to have cleared both the
|
|
6
6
|
* compute and the action phase; a transaction the indexer knows but hasn't fully
|
|
7
|
-
* described yet stays pending.
|
|
7
|
+
* described yet stays pending. The action phase matters because it is where the
|
|
8
|
+
* wallet actually emits the transfer: a transaction can pass compute and land
|
|
9
|
+
* un-aborted while moving nothing, with the seqno consumed either way. A failure
|
|
10
|
+
* comes back explained (`failure`) so the UI can say what went wrong and how to
|
|
11
|
+
* fix it.
|
|
8
12
|
*/
|
|
9
13
|
export declare const getTonTxStatus: TxStatusResolver<OtherChain.Ton>;
|
|
10
14
|
//# sourceMappingURL=ton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ton.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/status/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"ton.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/status/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAO9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AA8B9C;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAgC3D,CAAA"}
|
|
@@ -1,37 +1,18 @@
|
|
|
1
1
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { getTonTxFailure } from '@vultisig/core-chain/chains/ton/failure';
|
|
2
3
|
import { chainFeeCoin } from '@vultisig/core-chain/coin/chainFeeCoin';
|
|
3
4
|
import { rootApiUrl } from '@vultisig/core-config';
|
|
4
5
|
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
5
6
|
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
6
|
-
/**
|
|
7
|
-
* TVM exit codes 0 and 1 are the success conventions; any other code is a revert.
|
|
8
|
-
* An absent code means the message had no compute phase (a plain transfer to a
|
|
9
|
-
* wallet), which is not a failure.
|
|
10
|
-
*/
|
|
11
|
-
const hasComputePhaseFailed = (computePhase) => {
|
|
12
|
-
const exitCode = computePhase?.exit_code;
|
|
13
|
-
return exitCode !== undefined && exitCode !== 0 && exitCode !== 1;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* The action phase is where the wallet contract actually emits the outgoing
|
|
17
|
-
* transfer, so it is where the money moves. A transaction can pass its compute
|
|
18
|
-
* phase and land un-aborted while its action phase moved nothing — the seqno is
|
|
19
|
-
* consumed either way — so this is what separates a real send from a silent
|
|
20
|
-
* no-op. `result_code` is checked alongside `success` because indexers do not
|
|
21
|
-
* always populate both.
|
|
22
|
-
*/
|
|
23
|
-
const hasActionPhaseFailed = (actionPhase) => {
|
|
24
|
-
if (!actionPhase) {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
const { success, no_funds, result_code, skipped_actions } = actionPhase;
|
|
28
|
-
return success === false || no_funds === true || (result_code ?? 0) !== 0 || (skipped_actions ?? 0) > 0;
|
|
29
|
-
};
|
|
30
7
|
/**
|
|
31
8
|
* Resolves a TON transaction by the hash of the external message that carried it.
|
|
32
9
|
* Success requires the transaction to be un-aborted *and* to have cleared both the
|
|
33
10
|
* compute and the action phase; a transaction the indexer knows but hasn't fully
|
|
34
|
-
* described yet stays pending.
|
|
11
|
+
* described yet stays pending. The action phase matters because it is where the
|
|
12
|
+
* wallet actually emits the transfer: a transaction can pass compute and land
|
|
13
|
+
* un-aborted while moving nothing, with the seqno consumed either way. A failure
|
|
14
|
+
* comes back explained (`failure`) so the UI can say what went wrong and how to
|
|
15
|
+
* fix it.
|
|
35
16
|
*/
|
|
36
17
|
export const getTonTxStatus = async ({ hash }) => {
|
|
37
18
|
const url = `${rootApiUrl}/ton/v3/transactionsByMessage?msg_hash=${hash}&direction=in&limit=1`;
|
|
@@ -55,9 +36,7 @@ export const getTonTxStatus = async ({ hash }) => {
|
|
|
55
36
|
feeTicker: feeCoin.ticker,
|
|
56
37
|
}
|
|
57
38
|
: undefined;
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
hasActionPhaseFailed(description.action);
|
|
61
|
-
return { status: failed ? 'error' : 'success', receipt };
|
|
39
|
+
const failure = getTonTxFailure(description);
|
|
40
|
+
return failure ? { status: 'error', receipt, failure } : { status: 'success', receipt };
|
|
62
41
|
};
|
|
63
42
|
//# sourceMappingURL=ton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/status/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/status/resolvers/ton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAgC7D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAqC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACjF,MAAM,GAAG,GAAG,GAAG,UAAU,0CAA0C,IAAI,uBAAuB,CAAA;IAE9F,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,QAAQ,CAA0B,GAAG,CAAC,CAAC,CAAA;IAEvF,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC9C,CAAC;IAED,MAAM,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,CAAA;IAE1B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,6EAA6E;QAC7E,8CAA8C;QAC9C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC7C,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAA;IAC5B,MAAM,OAAO,GACX,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,EAAE;QAC7B,CAAC,CAAC;YACE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC;YACzB,WAAW,EAAE,OAAO,CAAC,QAAQ;YAC7B,SAAS,EAAE,OAAO,CAAC,MAAM;SAC1B;QACH,CAAC,CAAC,SAAS,CAAA;IAEf,MAAM,OAAO,GAAG,eAAe,CAAC,WAAW,CAAC,CAAA;IAE5C,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAA;AACzF,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/core-chain",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Blockchain chain logic shared across Vultisig clients",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -1010,6 +1010,11 @@
|
|
|
1010
1010
|
"import": "./dist/chains/ton/config.js",
|
|
1011
1011
|
"default": "./dist/chains/ton/config.js"
|
|
1012
1012
|
},
|
|
1013
|
+
"./chains/ton/failure": {
|
|
1014
|
+
"types": "./dist/chains/ton/failure.d.ts",
|
|
1015
|
+
"import": "./dist/chains/ton/failure.js",
|
|
1016
|
+
"default": "./dist/chains/ton/failure.js"
|
|
1017
|
+
},
|
|
1013
1018
|
"./chains/ton/jetton/symbol": {
|
|
1014
1019
|
"types": "./dist/chains/ton/jetton/symbol.d.ts",
|
|
1015
1020
|
"import": "./dist/chains/ton/jetton/symbol.js",
|
|
@@ -1055,6 +1060,16 @@
|
|
|
1055
1060
|
"import": "./dist/chains/ton/staking.js",
|
|
1056
1061
|
"default": "./dist/chains/ton/staking.js"
|
|
1057
1062
|
},
|
|
1063
|
+
"./chains/ton/wallet": {
|
|
1064
|
+
"types": "./dist/chains/ton/wallet.d.ts",
|
|
1065
|
+
"import": "./dist/chains/ton/wallet.js",
|
|
1066
|
+
"default": "./dist/chains/ton/wallet.js"
|
|
1067
|
+
},
|
|
1068
|
+
"./chains/ton/walletV5R1": {
|
|
1069
|
+
"types": "./dist/chains/ton/walletV5R1.d.ts",
|
|
1070
|
+
"import": "./dist/chains/ton/walletV5R1.js",
|
|
1071
|
+
"default": "./dist/chains/ton/walletV5R1.js"
|
|
1072
|
+
},
|
|
1058
1073
|
"./chains/tron/config": {
|
|
1059
1074
|
"types": "./dist/chains/tron/config.d.ts",
|
|
1060
1075
|
"import": "./dist/chains/tron/config.js",
|