@anywalletkit/wallet-ton 0.2.5 → 0.3.1
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/README.md +12 -4
- package/dist/{chunk-BLWBC6L2.js → chunk-RCL4PSJZ.js} +1 -1
- package/dist/chunk-RCL4PSJZ.js.map +1 -0
- package/dist/history.cjs.map +1 -1
- package/dist/history.d.cts +2 -2
- package/dist/history.d.ts +2 -2
- package/dist/history.js +1 -1
- package/dist/index.cjs +80 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -3
- package/dist/index.d.ts +39 -3
- package/dist/index.js +82 -16
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/dist/chunk-BLWBC6L2.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cell, StateInit, TupleReader, Address, TupleItem, Transaction, MessageRelaxed } from '@ton/core';
|
|
2
2
|
import { SignerError, IWalletAccountReadOnly, IWalletAccount, Signer, WriteOptions, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
|
|
3
|
-
export { HistoryFetch, HistoryUnavailableError, TonChainTx, TonHistoryBackend, TonHistoryCursor, TonHistoryOptions, TonHistoryPage, TonHistoryRaw, TonHistorySource, TonapiAction, TonapiEvent, V3Transaction, createTonHistory, decodeCursor as decodeHistoryCursor, encodeCursor as encodeHistoryCursor, mapActions as mapTonapiActions, mapTonapiEvent, mapToncenterTransaction, rawTonAddress, tonExplorerTxUrl, valueFlowTransfers } from './history.cjs';
|
|
3
|
+
export { HistoryFetch, HistoryUnavailableError, MappedActions, TonChainTx, TonHistoryBackend, TonHistoryCursor, TonHistoryOptions, TonHistoryPage, TonHistoryRaw, TonHistorySource, TonapiAccount, TonapiAction, TonapiEvent, TonapiJetton, V3Message, V3Transaction, createTonHistory, decodeCursor as decodeHistoryCursor, encodeCursor as encodeHistoryCursor, mapActions as mapTonapiActions, mapTonapiEvent, mapToncenterTransaction, rawTonAddress, tonExplorerTxUrl, valueFlowTransfers } from './history.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Set `globalThis.Buffer` to the `buffer` polyfill when the runtime has none (Hermes, browsers).
|
|
@@ -237,12 +237,26 @@ declare class SimulationError extends Error {
|
|
|
237
237
|
aborted?: boolean;
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* The external message was handed to the network but no definitive answer came back (no response,
|
|
242
|
+
* a timeout, a non-JSON body): it MAY be on chain. Do not sign again (the next seqno would pay
|
|
243
|
+
* twice) — watch `hash`, the body hash `sendTransaction` returns.
|
|
244
|
+
*/
|
|
245
|
+
declare class BroadcastUnknownError extends Error {
|
|
246
|
+
/** Always true: the transaction may be on its way. */
|
|
247
|
+
readonly maybeSent = true;
|
|
248
|
+
/** Hex hash of the signed body. */
|
|
249
|
+
readonly hash: string;
|
|
250
|
+
constructor(hash: string, cause: unknown);
|
|
251
|
+
}
|
|
240
252
|
|
|
241
253
|
/** JSON-RPC over one toncenter v2 endpoint. */
|
|
242
254
|
declare function tonCenterEndpoint(endpoint: TonEndpoint, opts?: {
|
|
243
255
|
fetch?: typeof fetch;
|
|
244
256
|
timeoutMs?: number;
|
|
245
257
|
}): TonRpc;
|
|
258
|
+
/** An endpoint answered with a refusal (`ok: false`): nothing was taken. A thrown fetch, a timeout or a non-JSON body may have been. */
|
|
259
|
+
declare function isAnsweredRefusal(e: unknown): boolean;
|
|
246
260
|
/** One RPC, or a failover RPC walking the configured list (`retries` extra rounds after the first full pass). */
|
|
247
261
|
declare function createTonRpc(config: TonConfig): TonRpc | undefined;
|
|
248
262
|
/** State of a TON account on chain. */
|
|
@@ -492,9 +506,14 @@ interface TonDescribedMessage {
|
|
|
492
506
|
jetton?: TonJettonDetails;
|
|
493
507
|
hasStateInit: boolean;
|
|
494
508
|
bodyBits: number;
|
|
509
|
+
/**
|
|
510
|
+
* Send mode the wallet sends the message with (IGNORE_ERRORS is always added for an external).
|
|
511
|
+
* 128 carries the whole remaining balance, 32 destroys the account when it is left empty.
|
|
512
|
+
*/
|
|
513
|
+
mode?: number;
|
|
495
514
|
}
|
|
496
515
|
/** Problems a TON description is flagged with. */
|
|
497
|
-
type TonWarningCode = 'zero-value' | 'non-bounceable-contract-call' | 'unknown-body' | 'large-forward-amount' | 'testnet-address' | 'mainnet-address' | 'exotic-workchain' | 'extended-actions';
|
|
516
|
+
type TonWarningCode = 'zero-value' | 'non-bounceable-contract-call' | 'unknown-body' | 'large-forward-amount' | 'testnet-address' | 'mainnet-address' | 'exotic-workchain' | 'extended-actions' | 'carries-all-balance' | 'destroys-account';
|
|
498
517
|
/** One flagged problem; `index` is the message it is about. */
|
|
499
518
|
interface TonWarning {
|
|
500
519
|
code: TonWarningCode;
|
|
@@ -584,6 +603,15 @@ declare class WalletAccountReadOnlyTon implements IWalletAccountReadOnly {
|
|
|
584
603
|
*/
|
|
585
604
|
getTokenBalance(token: string): Promise<bigint>;
|
|
586
605
|
protected stateInitOf(src: TonTransaction['stateInit']): StateInit | undefined;
|
|
606
|
+
/**
|
|
607
|
+
* A destination address with the checks every payment gets: workchain 0 or -1, and a friendly
|
|
608
|
+
* address's test-only flag matching the wallet's network. Used for a native message's `to` and a
|
|
609
|
+
* jetton transfer's recipient and response destination (round 3, L8).
|
|
610
|
+
*/
|
|
611
|
+
protected checkedAddress(to: string): {
|
|
612
|
+
address: Address;
|
|
613
|
+
bounceable: boolean;
|
|
614
|
+
};
|
|
587
615
|
protected transactionMessage(tx: TonTransaction): V5R1Message;
|
|
588
616
|
protected jettonTransferMessage(o: TonTransferOptions): Promise<V5R1Message>;
|
|
589
617
|
protected toMessages(tx: TonTransaction | TonTransaction[]): V5R1Message[];
|
|
@@ -730,6 +758,14 @@ declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWall
|
|
|
730
758
|
* Checks → seqno → preflight → signed body. The preflight runs on the
|
|
731
759
|
* zero-signed body (ignore_chksig), so nothing is signed before it passes.
|
|
732
760
|
*/
|
|
761
|
+
/**
|
|
762
|
+
* Refuse send modes that drain the wallet — 128 (the whole remaining balance) and 32 (the account
|
|
763
|
+
* destroyed once empty) — unless `allowDrainingTransactions`. Checked locally, before any seqno or
|
|
764
|
+
* emulation, so it holds with `simulate: false` too (round 3, M11); the emulation check stays.
|
|
765
|
+
*/
|
|
766
|
+
private assertNoDrain;
|
|
767
|
+
/** The send modes of a prebuilt V5R1 body; an unreadable body is left to the emulation and the node. */
|
|
768
|
+
private bodyModes;
|
|
733
769
|
private signMessages;
|
|
734
770
|
private preflight;
|
|
735
771
|
/** Sign without broadcasting. Returns the external-message BODY as base64 BoC (pass it back to sendTransaction as a Cell). */
|
|
@@ -782,4 +818,4 @@ declare class WalletManagerTon extends WalletManager<WalletAccountTon, TonConfig
|
|
|
782
818
|
getFeeRates(): Promise<FeeRates>;
|
|
783
819
|
}
|
|
784
820
|
|
|
785
|
-
export { CAIP2, DEFAULT_SEND_MODE, DEFAULT_TONAPI, type DecodedBody, type EmulateOptions, type EmulationOutcome, type EmulationSource, type EmulationVerdict, type GetMethodResult, JETTON_TRANSFER_OP, MAINNET_GLOBAL_ID, MAX_ACTIONS, MessageIsTransactionError, type ParsedV5R1Body, SEND_MODE, SimulationError, TESTNET_GLOBAL_ID, TON_BASE_PATH, TON_MNEMONIC_PATH, type TonAccountState, type TonAccountStatus, type TonAddressParts, TonCenter, type TonConfig, type TonDescribedKind, type TonDescribedMessage, type TonDescription, type TonEmulateConfig, type TonEndpoint, type TonFees, type TonJettonDetails, type TonProof, type TonProofRequest, type TonProvider, type TonReceipt, type TonRisk, type TonRpc, type TonSendable, type TonSignDataPayload, type TonSignDataRequest, type TonSignedData, type TonSimulation, type TonSimulationSource, type TonTransaction, type TonTransferOptions, type TonWarning, type TonWarningCode, UnsafeTransactionError, type V5R1Message, type V5R1SigningParams, type V5R1WalletIdParts, V5R1_CODE_HEX, V5R1_OP, WalletAccountReadOnlyTon, WalletAccountTon, WalletManagerTon, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, parseEmulation, parseTonapiConsequences, parseTonapiRisk, parseTonapiTrace, parseV5R1Body, resolveEmulate, runEmulation, tonCenterEndpoint, tonProofDigest, tonSignDataDigest, v5r1Address, v5r1Code, v5r1ExternalMessage, v5r1PackSigned, v5r1PackUnsigned, v5r1SigningMessage, v5r1StateInit, v5r1WalletId };
|
|
821
|
+
export { BroadcastUnknownError, CAIP2, DEFAULT_SEND_MODE, DEFAULT_TONAPI, type DecodedBody, type EmulateOptions, type EmulationOutcome, type EmulationSource, type EmulationVerdict, type GetMethodResult, JETTON_TRANSFER_OP, MAINNET_GLOBAL_ID, MAX_ACTIONS, MessageIsTransactionError, type ParsedV5R1Body, SEND_MODE, SimulationError, TESTNET_GLOBAL_ID, TON_BASE_PATH, TON_MNEMONIC_PATH, type TonAccountState, type TonAccountStatus, type TonAddressParts, TonCenter, type TonConfig, type TonDescribedKind, type TonDescribedMessage, type TonDescription, type TonEmulateConfig, type TonEndpoint, type TonFees, type TonJettonDetails, type TonProof, type TonProofRequest, type TonProvider, type TonReceipt, type TonRisk, type TonRpc, type TonSendable, type TonSignDataPayload, type TonSignDataRequest, type TonSignedData, type TonSimulation, type TonSimulationSource, type TonTransaction, type TonTransferOptions, type TonWarning, type TonWarningCode, UnsafeTransactionError, type V5R1Message, type V5R1SigningParams, type V5R1WalletIdParts, V5R1_CODE_HEX, V5R1_OP, WalletAccountReadOnlyTon, WalletAccountTon, WalletManagerTon, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, isAnsweredRefusal, parseEmulation, parseTonapiConsequences, parseTonapiRisk, parseTonapiTrace, parseV5R1Body, resolveEmulate, runEmulation, tonCenterEndpoint, tonProofDigest, tonSignDataDigest, v5r1Address, v5r1Code, v5r1ExternalMessage, v5r1PackSigned, v5r1PackUnsigned, v5r1SigningMessage, v5r1StateInit, v5r1WalletId };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cell, StateInit, TupleReader, Address, TupleItem, Transaction, MessageRelaxed } from '@ton/core';
|
|
2
2
|
import { SignerError, IWalletAccountReadOnly, IWalletAccount, Signer, WriteOptions, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
|
|
3
|
-
export { HistoryFetch, HistoryUnavailableError, TonChainTx, TonHistoryBackend, TonHistoryCursor, TonHistoryOptions, TonHistoryPage, TonHistoryRaw, TonHistorySource, TonapiAction, TonapiEvent, V3Transaction, createTonHistory, decodeCursor as decodeHistoryCursor, encodeCursor as encodeHistoryCursor, mapActions as mapTonapiActions, mapTonapiEvent, mapToncenterTransaction, rawTonAddress, tonExplorerTxUrl, valueFlowTransfers } from './history.js';
|
|
3
|
+
export { HistoryFetch, HistoryUnavailableError, MappedActions, TonChainTx, TonHistoryBackend, TonHistoryCursor, TonHistoryOptions, TonHistoryPage, TonHistoryRaw, TonHistorySource, TonapiAccount, TonapiAction, TonapiEvent, TonapiJetton, V3Message, V3Transaction, createTonHistory, decodeCursor as decodeHistoryCursor, encodeCursor as encodeHistoryCursor, mapActions as mapTonapiActions, mapTonapiEvent, mapToncenterTransaction, rawTonAddress, tonExplorerTxUrl, valueFlowTransfers } from './history.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Set `globalThis.Buffer` to the `buffer` polyfill when the runtime has none (Hermes, browsers).
|
|
@@ -237,12 +237,26 @@ declare class SimulationError extends Error {
|
|
|
237
237
|
aborted?: boolean;
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* The external message was handed to the network but no definitive answer came back (no response,
|
|
242
|
+
* a timeout, a non-JSON body): it MAY be on chain. Do not sign again (the next seqno would pay
|
|
243
|
+
* twice) — watch `hash`, the body hash `sendTransaction` returns.
|
|
244
|
+
*/
|
|
245
|
+
declare class BroadcastUnknownError extends Error {
|
|
246
|
+
/** Always true: the transaction may be on its way. */
|
|
247
|
+
readonly maybeSent = true;
|
|
248
|
+
/** Hex hash of the signed body. */
|
|
249
|
+
readonly hash: string;
|
|
250
|
+
constructor(hash: string, cause: unknown);
|
|
251
|
+
}
|
|
240
252
|
|
|
241
253
|
/** JSON-RPC over one toncenter v2 endpoint. */
|
|
242
254
|
declare function tonCenterEndpoint(endpoint: TonEndpoint, opts?: {
|
|
243
255
|
fetch?: typeof fetch;
|
|
244
256
|
timeoutMs?: number;
|
|
245
257
|
}): TonRpc;
|
|
258
|
+
/** An endpoint answered with a refusal (`ok: false`): nothing was taken. A thrown fetch, a timeout or a non-JSON body may have been. */
|
|
259
|
+
declare function isAnsweredRefusal(e: unknown): boolean;
|
|
246
260
|
/** One RPC, or a failover RPC walking the configured list (`retries` extra rounds after the first full pass). */
|
|
247
261
|
declare function createTonRpc(config: TonConfig): TonRpc | undefined;
|
|
248
262
|
/** State of a TON account on chain. */
|
|
@@ -492,9 +506,14 @@ interface TonDescribedMessage {
|
|
|
492
506
|
jetton?: TonJettonDetails;
|
|
493
507
|
hasStateInit: boolean;
|
|
494
508
|
bodyBits: number;
|
|
509
|
+
/**
|
|
510
|
+
* Send mode the wallet sends the message with (IGNORE_ERRORS is always added for an external).
|
|
511
|
+
* 128 carries the whole remaining balance, 32 destroys the account when it is left empty.
|
|
512
|
+
*/
|
|
513
|
+
mode?: number;
|
|
495
514
|
}
|
|
496
515
|
/** Problems a TON description is flagged with. */
|
|
497
|
-
type TonWarningCode = 'zero-value' | 'non-bounceable-contract-call' | 'unknown-body' | 'large-forward-amount' | 'testnet-address' | 'mainnet-address' | 'exotic-workchain' | 'extended-actions';
|
|
516
|
+
type TonWarningCode = 'zero-value' | 'non-bounceable-contract-call' | 'unknown-body' | 'large-forward-amount' | 'testnet-address' | 'mainnet-address' | 'exotic-workchain' | 'extended-actions' | 'carries-all-balance' | 'destroys-account';
|
|
498
517
|
/** One flagged problem; `index` is the message it is about. */
|
|
499
518
|
interface TonWarning {
|
|
500
519
|
code: TonWarningCode;
|
|
@@ -584,6 +603,15 @@ declare class WalletAccountReadOnlyTon implements IWalletAccountReadOnly {
|
|
|
584
603
|
*/
|
|
585
604
|
getTokenBalance(token: string): Promise<bigint>;
|
|
586
605
|
protected stateInitOf(src: TonTransaction['stateInit']): StateInit | undefined;
|
|
606
|
+
/**
|
|
607
|
+
* A destination address with the checks every payment gets: workchain 0 or -1, and a friendly
|
|
608
|
+
* address's test-only flag matching the wallet's network. Used for a native message's `to` and a
|
|
609
|
+
* jetton transfer's recipient and response destination (round 3, L8).
|
|
610
|
+
*/
|
|
611
|
+
protected checkedAddress(to: string): {
|
|
612
|
+
address: Address;
|
|
613
|
+
bounceable: boolean;
|
|
614
|
+
};
|
|
587
615
|
protected transactionMessage(tx: TonTransaction): V5R1Message;
|
|
588
616
|
protected jettonTransferMessage(o: TonTransferOptions): Promise<V5R1Message>;
|
|
589
617
|
protected toMessages(tx: TonTransaction | TonTransaction[]): V5R1Message[];
|
|
@@ -730,6 +758,14 @@ declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWall
|
|
|
730
758
|
* Checks → seqno → preflight → signed body. The preflight runs on the
|
|
731
759
|
* zero-signed body (ignore_chksig), so nothing is signed before it passes.
|
|
732
760
|
*/
|
|
761
|
+
/**
|
|
762
|
+
* Refuse send modes that drain the wallet — 128 (the whole remaining balance) and 32 (the account
|
|
763
|
+
* destroyed once empty) — unless `allowDrainingTransactions`. Checked locally, before any seqno or
|
|
764
|
+
* emulation, so it holds with `simulate: false` too (round 3, M11); the emulation check stays.
|
|
765
|
+
*/
|
|
766
|
+
private assertNoDrain;
|
|
767
|
+
/** The send modes of a prebuilt V5R1 body; an unreadable body is left to the emulation and the node. */
|
|
768
|
+
private bodyModes;
|
|
733
769
|
private signMessages;
|
|
734
770
|
private preflight;
|
|
735
771
|
/** Sign without broadcasting. Returns the external-message BODY as base64 BoC (pass it back to sendTransaction as a Cell). */
|
|
@@ -782,4 +818,4 @@ declare class WalletManagerTon extends WalletManager<WalletAccountTon, TonConfig
|
|
|
782
818
|
getFeeRates(): Promise<FeeRates>;
|
|
783
819
|
}
|
|
784
820
|
|
|
785
|
-
export { CAIP2, DEFAULT_SEND_MODE, DEFAULT_TONAPI, type DecodedBody, type EmulateOptions, type EmulationOutcome, type EmulationSource, type EmulationVerdict, type GetMethodResult, JETTON_TRANSFER_OP, MAINNET_GLOBAL_ID, MAX_ACTIONS, MessageIsTransactionError, type ParsedV5R1Body, SEND_MODE, SimulationError, TESTNET_GLOBAL_ID, TON_BASE_PATH, TON_MNEMONIC_PATH, type TonAccountState, type TonAccountStatus, type TonAddressParts, TonCenter, type TonConfig, type TonDescribedKind, type TonDescribedMessage, type TonDescription, type TonEmulateConfig, type TonEndpoint, type TonFees, type TonJettonDetails, type TonProof, type TonProofRequest, type TonProvider, type TonReceipt, type TonRisk, type TonRpc, type TonSendable, type TonSignDataPayload, type TonSignDataRequest, type TonSignedData, type TonSimulation, type TonSimulationSource, type TonTransaction, type TonTransferOptions, type TonWarning, type TonWarningCode, UnsafeTransactionError, type V5R1Message, type V5R1SigningParams, type V5R1WalletIdParts, V5R1_CODE_HEX, V5R1_OP, WalletAccountReadOnlyTon, WalletAccountTon, WalletManagerTon, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, parseEmulation, parseTonapiConsequences, parseTonapiRisk, parseTonapiTrace, parseV5R1Body, resolveEmulate, runEmulation, tonCenterEndpoint, tonProofDigest, tonSignDataDigest, v5r1Address, v5r1Code, v5r1ExternalMessage, v5r1PackSigned, v5r1PackUnsigned, v5r1SigningMessage, v5r1StateInit, v5r1WalletId };
|
|
821
|
+
export { BroadcastUnknownError, CAIP2, DEFAULT_SEND_MODE, DEFAULT_TONAPI, type DecodedBody, type EmulateOptions, type EmulationOutcome, type EmulationSource, type EmulationVerdict, type GetMethodResult, JETTON_TRANSFER_OP, MAINNET_GLOBAL_ID, MAX_ACTIONS, MessageIsTransactionError, type ParsedV5R1Body, SEND_MODE, SimulationError, TESTNET_GLOBAL_ID, TON_BASE_PATH, TON_MNEMONIC_PATH, type TonAccountState, type TonAccountStatus, type TonAddressParts, TonCenter, type TonConfig, type TonDescribedKind, type TonDescribedMessage, type TonDescription, type TonEmulateConfig, type TonEndpoint, type TonFees, type TonJettonDetails, type TonProof, type TonProofRequest, type TonProvider, type TonReceipt, type TonRisk, type TonRpc, type TonSendable, type TonSignDataPayload, type TonSignDataRequest, type TonSignedData, type TonSimulation, type TonSimulationSource, type TonTransaction, type TonTransferOptions, type TonWarning, type TonWarningCode, UnsafeTransactionError, type V5R1Message, type V5R1SigningParams, type V5R1WalletIdParts, V5R1_CODE_HEX, V5R1_OP, WalletAccountReadOnlyTon, WalletAccountTon, WalletManagerTon, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, isAnsweredRefusal, parseEmulation, parseTonapiConsequences, parseTonapiRisk, parseTonapiTrace, parseV5R1Body, resolveEmulate, runEmulation, tonCenterEndpoint, tonProofDigest, tonSignDataDigest, v5r1Address, v5r1Code, v5r1ExternalMessage, v5r1PackSigned, v5r1PackUnsigned, v5r1SigningMessage, v5r1StateInit, v5r1WalletId };
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
rawTonAddress,
|
|
11
11
|
tonExplorerTxUrl,
|
|
12
12
|
valueFlowTransfers
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RCL4PSJZ.js";
|
|
14
14
|
|
|
15
15
|
// src/buffer-global.ts
|
|
16
16
|
import { Buffer } from "buffer";
|
|
@@ -47,6 +47,17 @@ var SimulationError = class extends Error {
|
|
|
47
47
|
this.aborted = details.aborted ?? false;
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
|
+
var BroadcastUnknownError = class extends Error {
|
|
51
|
+
/** Always true: the transaction may be on its way. */
|
|
52
|
+
maybeSent = true;
|
|
53
|
+
/** Hex hash of the signed body. */
|
|
54
|
+
hash;
|
|
55
|
+
constructor(hash, cause) {
|
|
56
|
+
super(`Broadcast outcome unknown for ${hash}: ${cause instanceof Error ? cause.message.slice(0, 200) : String(cause).slice(0, 200)}`, { cause });
|
|
57
|
+
this.name = "BroadcastUnknownError";
|
|
58
|
+
this.hash = hash;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
50
61
|
|
|
51
62
|
// src/toncenter.ts
|
|
52
63
|
import { NetworkError } from "@anywalletkit/core";
|
|
@@ -84,12 +95,15 @@ function tonCenterEndpoint(endpoint, opts = {}) {
|
|
|
84
95
|
}
|
|
85
96
|
if (!res.ok || json.ok !== true) {
|
|
86
97
|
const detail = typeof json.error === "string" ? json.error : JSON.stringify(json.error ?? json);
|
|
87
|
-
throw new NetworkError(`${method}: ${detail} (HTTP ${res.status})`, { provider: url });
|
|
98
|
+
throw Object.assign(new NetworkError(`${method}: ${detail} (HTTP ${res.status})`, { provider: url }), { answered: true });
|
|
88
99
|
}
|
|
89
100
|
return json.result;
|
|
90
101
|
}
|
|
91
102
|
};
|
|
92
103
|
}
|
|
104
|
+
function isAnsweredRefusal(e) {
|
|
105
|
+
return e?.answered === true;
|
|
106
|
+
}
|
|
93
107
|
function createTonRpc(config) {
|
|
94
108
|
const target = config.tonClient ?? config.provider;
|
|
95
109
|
if (target === void 0) return void 0;
|
|
@@ -102,14 +116,17 @@ function createTonRpc(config) {
|
|
|
102
116
|
return {
|
|
103
117
|
async call(method, params) {
|
|
104
118
|
let lastError;
|
|
119
|
+
let answered = true;
|
|
105
120
|
for (let i = 0; i < attempts; i++) {
|
|
106
121
|
try {
|
|
107
122
|
return await list[i % list.length].call(method, params);
|
|
108
123
|
} catch (e) {
|
|
109
124
|
lastError = e;
|
|
125
|
+
answered &&= isAnsweredRefusal(e);
|
|
110
126
|
}
|
|
111
127
|
}
|
|
112
|
-
|
|
128
|
+
const err = new NetworkError(`All TON endpoints failed for ${method}`, { cause: lastError });
|
|
129
|
+
throw answered ? Object.assign(err, { answered: true }) : err;
|
|
113
130
|
}
|
|
114
131
|
};
|
|
115
132
|
}
|
|
@@ -645,6 +662,19 @@ function describeOne(i, to, value, body, hasStateInit, bounceableOverride, warni
|
|
|
645
662
|
return item;
|
|
646
663
|
}
|
|
647
664
|
var hex = (n) => `0x${n.toString(16).padStart(8, "0")}`;
|
|
665
|
+
var IGNORE_ERRORS = 2;
|
|
666
|
+
function sendModeOf(sendMode) {
|
|
667
|
+
return (sendMode ?? DEFAULT_SEND_MODE) | IGNORE_ERRORS;
|
|
668
|
+
}
|
|
669
|
+
function drainModes(mode) {
|
|
670
|
+
return [...(mode & 128) !== 0 ? ["carries-all-balance"] : [], ...(mode & 32) !== 0 ? ["destroys-account"] : []];
|
|
671
|
+
}
|
|
672
|
+
function withMode(i, item, mode, warnings) {
|
|
673
|
+
for (const code of drainModes(mode)) {
|
|
674
|
+
warnings.push({ code, message: code === "carries-all-balance" ? "send mode 128: the message carries the whole remaining balance" : "send mode 32: the wallet account is destroyed once it is empty", index: i });
|
|
675
|
+
}
|
|
676
|
+
return { ...item, mode };
|
|
677
|
+
}
|
|
648
678
|
function describeMessageRelaxed(i, m, warnings, ctx = {}) {
|
|
649
679
|
if (m.info.type !== "internal") {
|
|
650
680
|
warnings.push({ code: "unknown-body", message: "not an internal message", index: i });
|
|
@@ -666,7 +696,7 @@ function describeTransaction(tx, ctx = {}) {
|
|
|
666
696
|
return { kind: "contract-call", items, warnings };
|
|
667
697
|
}
|
|
668
698
|
external2 = { seqno: parsed.seqno, validUntil: parsed.validUntil, walletId: parsed.walletId, signed: parsed.signed };
|
|
669
|
-
parsed.messages.forEach((m, i) => items.push(describeMessageRelaxed(i, m.message, warnings, ctx)));
|
|
699
|
+
parsed.messages.forEach((m, i) => items.push(withMode(i, describeMessageRelaxed(i, m.message, warnings, ctx), m.mode, warnings)));
|
|
670
700
|
} else {
|
|
671
701
|
const list = Array.isArray(tx) ? tx : [tx];
|
|
672
702
|
list.forEach((t, i) => {
|
|
@@ -684,7 +714,7 @@ function describeTransaction(tx, ctx = {}) {
|
|
|
684
714
|
} catch {
|
|
685
715
|
warnings.push({ code: "unknown-body", message: "bodyBoc is not a valid BoC", index: i });
|
|
686
716
|
}
|
|
687
|
-
items.push(describeOne(i, to, BigInt(t.value), body, t.stateInit !== void 0, t.bounceable, warnings, ctx));
|
|
717
|
+
items.push(withMode(i, describeOne(i, to, BigInt(t.value), body, t.stateInit !== void 0, t.bounceable, warnings, ctx), sendModeOf(t.sendMode), warnings));
|
|
688
718
|
});
|
|
689
719
|
}
|
|
690
720
|
const kinds = new Set(items.map((x) => x.kind));
|
|
@@ -790,25 +820,34 @@ var WalletAccountReadOnlyTon = class {
|
|
|
790
820
|
if (src instanceof Cell4) return loadStateInit(src.beginParse());
|
|
791
821
|
return src;
|
|
792
822
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
823
|
+
/**
|
|
824
|
+
* A destination address with the checks every payment gets: workchain 0 or -1, and a friendly
|
|
825
|
+
* address's test-only flag matching the wallet's network. Used for a native message's `to` and a
|
|
826
|
+
* jetton transfer's recipient and response destination (round 3, L8).
|
|
827
|
+
*/
|
|
828
|
+
checkedAddress(to) {
|
|
796
829
|
let address;
|
|
797
830
|
let bounceable = true;
|
|
798
831
|
let testOnly;
|
|
799
|
-
if (Address4.isFriendly(
|
|
800
|
-
const f = Address4.parseFriendly(
|
|
832
|
+
if (Address4.isFriendly(to)) {
|
|
833
|
+
const f = Address4.parseFriendly(to);
|
|
801
834
|
address = f.address;
|
|
802
835
|
bounceable = f.isBounceable;
|
|
803
836
|
testOnly = f.isTestOnly;
|
|
804
837
|
} else {
|
|
805
|
-
address = Address4.parse(
|
|
838
|
+
address = Address4.parse(to);
|
|
806
839
|
}
|
|
807
840
|
if (address.workChain !== 0 && address.workChain !== -1) throw new UnsafeTransactionError("exotic-workchain", `Refusing to send to workchain ${address.workChain}.`);
|
|
808
841
|
const testnet = this._config.network === "testnet";
|
|
809
842
|
if (testOnly !== void 0 && testOnly !== testnet) {
|
|
810
843
|
throw new UnsafeTransactionError("network-mismatch", testOnly ? "Test-only address on a mainnet wallet." : "Mainnet address on a testnet wallet.");
|
|
811
844
|
}
|
|
845
|
+
return { address, bounceable };
|
|
846
|
+
}
|
|
847
|
+
transactionMessage(tx) {
|
|
848
|
+
const value = big(tx.value);
|
|
849
|
+
if (value <= 0n) throw new UnsafeTransactionError("zero-value", "TON message value must be positive.");
|
|
850
|
+
const { address, bounceable } = this.checkedAddress(tx.to);
|
|
812
851
|
const body = tx.body instanceof Cell4 ? tx.body : typeof tx.body === "string" ? tx.body === "" ? void 0 : commentCell(tx.body) : tx.bodyBoc ? Cell4.fromBase64(tx.bodyBoc) : void 0;
|
|
813
852
|
const init = this.stateInitOf(tx.stateInit);
|
|
814
853
|
const message = internal({ to: address, value, bounce: tx.bounceable ?? bounceable, ...body ? { body } : {}, ...init ? { init } : {} });
|
|
@@ -817,14 +856,15 @@ var WalletAccountReadOnlyTon = class {
|
|
|
817
856
|
async jettonTransferMessage(o) {
|
|
818
857
|
const amount = big(o.amount);
|
|
819
858
|
if (amount <= 0n) throw new UnsafeTransactionError("zero-value", "Jetton amount must be positive.");
|
|
820
|
-
const recipient =
|
|
859
|
+
const recipient = this.checkedAddress(o.recipient).address;
|
|
860
|
+
const response = o.responseDestination ? this.checkedAddress(o.responseDestination).address : void 0;
|
|
821
861
|
const jw = await this.getJettonWalletAddress(o.token);
|
|
822
862
|
await this.jettonWalletData(o.token, jw);
|
|
823
863
|
const forwardTonAmount = o.forwardTonAmount !== void 0 ? big(o.forwardTonAmount) : 1n;
|
|
824
864
|
if (o.memo !== void 0 && o.forwardPayload !== void 0) throw new UnsafeTransactionError("memo-and-payload", "Pass either memo or forwardPayload, not both: a jetton transfer carries one forward payload.");
|
|
825
865
|
const payload = o.forwardPayload ?? o.memo;
|
|
826
866
|
const forwardPayload = payload === void 0 ? null : typeof payload === "string" ? commentCell(payload) : payload;
|
|
827
|
-
const body = beginCell3().storeUint(JETTON_TRANSFER_OP2, 32).storeUint(o.queryId !== void 0 ? BigInt(o.queryId) : randomQueryId(), 64).storeCoins(amount).storeAddress(recipient).storeAddress(
|
|
867
|
+
const body = beginCell3().storeUint(JETTON_TRANSFER_OP2, 32).storeUint(o.queryId !== void 0 ? BigInt(o.queryId) : randomQueryId(), 64).storeCoins(amount).storeAddress(recipient).storeAddress(response ?? this._address).storeMaybeRef(o.customPayload ?? null).storeCoins(forwardTonAmount).storeMaybeRef(forwardPayload).endCell();
|
|
828
868
|
const attached = o.attachedValue !== void 0 ? big(o.attachedValue) : (this._config.jettonAttachedValue !== void 0 ? big(this._config.jettonAttachedValue) : DEFAULT_JETTON_ATTACHED) + forwardTonAmount;
|
|
829
869
|
return { message: internal({ to: jw, value: attached, bounce: true, body }) };
|
|
830
870
|
}
|
|
@@ -1081,7 +1121,22 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1081
1121
|
* Checks → seqno → preflight → signed body. The preflight runs on the
|
|
1082
1122
|
* zero-signed body (ignore_chksig), so nothing is signed before it passes.
|
|
1083
1123
|
*/
|
|
1124
|
+
/**
|
|
1125
|
+
* Refuse send modes that drain the wallet — 128 (the whole remaining balance) and 32 (the account
|
|
1126
|
+
* destroyed once empty) — unless `allowDrainingTransactions`. Checked locally, before any seqno or
|
|
1127
|
+
* emulation, so it holds with `simulate: false` too (round 3, M11); the emulation check stays.
|
|
1128
|
+
*/
|
|
1129
|
+
assertNoDrain(modes) {
|
|
1130
|
+
if (this._config.allowDrainingTransactions === true) return;
|
|
1131
|
+
const found = modes.flatMap(drainModes);
|
|
1132
|
+
if (found.length) throw new UnsafeTransactionError("drain", `Refusing a message with send mode ${found.includes("carries-all-balance") ? "128 (it carries the whole remaining balance)" : "32 (it destroys the wallet account once empty)"}; set allowDrainingTransactions to override.`);
|
|
1133
|
+
}
|
|
1134
|
+
/** The send modes of a prebuilt V5R1 body; an unreadable body is left to the emulation and the node. */
|
|
1135
|
+
bodyModes(body) {
|
|
1136
|
+
return parseV5R1Body(body)?.messages.map((m) => m.mode) ?? [];
|
|
1137
|
+
}
|
|
1084
1138
|
async signMessages(messages, limit, op) {
|
|
1139
|
+
this.assertNoDrain(messages.map((m) => sendModeOf(m.mode)));
|
|
1085
1140
|
const want = messages.reduce((sum, m) => sum + (m.message.info.type === "internal" ? m.message.info.value.coins : 0n), 0n);
|
|
1086
1141
|
if (want > 0n) {
|
|
1087
1142
|
const balance = await this.getBalance();
|
|
@@ -1113,6 +1168,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1113
1168
|
/** Sign without broadcasting. Returns the external-message BODY as base64 BoC (pass it back to sendTransaction as a Cell). */
|
|
1114
1169
|
async signTransaction(tx, options = {}) {
|
|
1115
1170
|
if (tx instanceof Cell5) {
|
|
1171
|
+
this.assertNoDrain(this.bodyModes(tx));
|
|
1116
1172
|
await this.preflight(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1117
1173
|
return tx.toBoc().toString("base64");
|
|
1118
1174
|
}
|
|
@@ -1122,12 +1178,19 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1122
1178
|
async broadcast(body) {
|
|
1123
1179
|
const rpc = this.requireRpc("send transactions");
|
|
1124
1180
|
const init = await this.initIfNeeded();
|
|
1125
|
-
|
|
1126
|
-
|
|
1181
|
+
const hash = body.hash().toString("hex");
|
|
1182
|
+
try {
|
|
1183
|
+
await rpc.sendBoc(v5r1ExternalMessage(this._address, body, init));
|
|
1184
|
+
} catch (e) {
|
|
1185
|
+
if (isAnsweredRefusal(e)) throw e;
|
|
1186
|
+
throw new BroadcastUnknownError(hash, e);
|
|
1187
|
+
}
|
|
1188
|
+
return hash;
|
|
1127
1189
|
}
|
|
1128
1190
|
/** Sign and broadcast; `hash` is the body hash (hex) — resolve it with getTransactionReceipt. */
|
|
1129
1191
|
async sendTransaction(tx, options = {}) {
|
|
1130
1192
|
this.requireRpc("send transactions");
|
|
1193
|
+
if (tx instanceof Cell5) this.assertNoDrain(this.bodyModes(tx));
|
|
1131
1194
|
const { body, fee } = tx instanceof Cell5 ? { body: tx, fee: await this.preflight(tx, feeLimit(this._config.transactionMaxFee, options), "transaction") } : await this.signMessages(this.toMessages(tx), feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1132
1195
|
return { hash: await this.broadcast(body), fee };
|
|
1133
1196
|
}
|
|
@@ -1151,7 +1214,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1151
1214
|
|
|
1152
1215
|
// src/manager.ts
|
|
1153
1216
|
import { LocalSigner as LocalSigner2, SignerError as SignerError2, WalletManager, isSeedSigner, zeroize } from "@anywalletkit/core";
|
|
1154
|
-
import { mnemonicToPrivateKey } from "@ton/crypto";
|
|
1217
|
+
import { mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto";
|
|
1155
1218
|
var TON_BASE_PATH = "m/44'/607'";
|
|
1156
1219
|
var TON_MNEMONIC_PATH = "ton-mnemonic";
|
|
1157
1220
|
var WalletManagerTon = class _WalletManagerTon extends WalletManager {
|
|
@@ -1166,6 +1229,7 @@ var WalletManagerTon = class _WalletManagerTon extends WalletManager {
|
|
|
1166
1229
|
static async fromTonMnemonic(words, config = {}) {
|
|
1167
1230
|
const list = (Array.isArray(words) ? words : words.trim().split(/\s+/)).map((w) => w.toLowerCase());
|
|
1168
1231
|
if (list.length !== 24) throw new Error("A TON mnemonic has 24 words.");
|
|
1232
|
+
if (!await mnemonicValidate(list)) throw new Error("Not a valid TON mnemonic: check the words (a typo would open a different, empty wallet).");
|
|
1169
1233
|
const pair = await mnemonicToPrivateKey(list);
|
|
1170
1234
|
const privateKey = new Uint8Array(pair.secretKey.subarray(0, 32));
|
|
1171
1235
|
const publicKey = new Uint8Array(pair.publicKey);
|
|
@@ -1232,6 +1296,7 @@ var WalletManagerTon = class _WalletManagerTon extends WalletManager {
|
|
|
1232
1296
|
// src/index.ts
|
|
1233
1297
|
installBufferGlobal();
|
|
1234
1298
|
export {
|
|
1299
|
+
BroadcastUnknownError,
|
|
1235
1300
|
CAIP2,
|
|
1236
1301
|
DEFAULT_SEND_MODE,
|
|
1237
1302
|
DEFAULT_TONAPI,
|
|
@@ -1265,6 +1330,7 @@ export {
|
|
|
1265
1330
|
emulateViaTonapi,
|
|
1266
1331
|
encodeCursor as encodeHistoryCursor,
|
|
1267
1332
|
installBufferGlobal,
|
|
1333
|
+
isAnsweredRefusal,
|
|
1268
1334
|
mapActions as mapTonapiActions,
|
|
1269
1335
|
mapTonapiEvent,
|
|
1270
1336
|
mapToncenterTransaction,
|