@anywalletkit/wallet-ton 0.3.1 → 0.5.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/dist/{chunk-RCL4PSJZ.js → chunk-ZFENRKRW.js} +1 -1
- package/dist/{chunk-RCL4PSJZ.js.map → chunk-ZFENRKRW.js.map} +1 -1
- package/dist/history.cjs.map +1 -1
- package/dist/history.js +1 -1
- package/dist/index.cjs +107 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -11
- package/dist/index.d.ts +32 -11
- package/dist/index.js +104 -26
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -67,6 +67,12 @@ interface TonConfig {
|
|
|
67
67
|
validUntilSeconds?: number;
|
|
68
68
|
/** Nanotons attached to a jetton transfer on top of `forwardTonAmount` (default 0.05 TON). */
|
|
69
69
|
jettonAttachedValue?: bigint | number | string;
|
|
70
|
+
/**
|
|
71
|
+
* Most nanotons a jetton `transfer()` may attach to the jetton-wallet call, `forwardTonAmount`
|
|
72
|
+
* included (default 1 TON). The contract that receives them is the one the jetton master names,
|
|
73
|
+
* so a fake master gets all of it: the cap bounds what such a call can cost.
|
|
74
|
+
*/
|
|
75
|
+
maxJettonAttachedValue?: bigint | number | string;
|
|
70
76
|
/**
|
|
71
77
|
* 'mainnet' (ton:-239, default) or 'testnet' (ton:-3). Sets the CAIP-2 id, the address flags and the
|
|
72
78
|
* wallet_id network (-239 / -3), so a testnet wallet has its own address and its signed messages are
|
|
@@ -122,8 +128,14 @@ interface TonTransferOptions {
|
|
|
122
128
|
memo?: string;
|
|
123
129
|
/** Jetton only: custom payload cell (rarely needed; e.g. mintless jettons). */
|
|
124
130
|
customPayload?: Cell;
|
|
125
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Jetton only: where excess TON returns (default: this wallet). Another address is refused
|
|
133
|
+
* unless `allowForeignResponseDestination` is set: it receives TON the policies' recipient
|
|
134
|
+
* check never sees.
|
|
135
|
+
*/
|
|
126
136
|
responseDestination?: string;
|
|
137
|
+
/** Jetton only: let `responseDestination` be another address than this wallet. Off by default. */
|
|
138
|
+
allowForeignResponseDestination?: boolean;
|
|
127
139
|
/** Jetton only: query id (default random). */
|
|
128
140
|
queryId?: bigint | number;
|
|
129
141
|
/** Jetton only: nanotons attached to the jetton-wallet call (default config.jettonAttachedValue + forwardTonAmount). */
|
|
@@ -469,12 +481,6 @@ interface ParsedV5R1Body {
|
|
|
469
481
|
/** Parse a signed (or zero-signed) V5R1 external body back into its messages. Returns null for anything else. */
|
|
470
482
|
declare function parseV5R1Body(body: Cell): ParsedV5R1Body | null;
|
|
471
483
|
|
|
472
|
-
/**
|
|
473
|
-
* "What am I signing" for TON — offline. Decodes the messages of a
|
|
474
|
-
* {@link TonSendable} (or a prebuilt V5R1 body) into human-checkable items and
|
|
475
|
-
* flags the classic mistakes before any key is touched.
|
|
476
|
-
*/
|
|
477
|
-
|
|
478
484
|
/** TEP-74 `transfer` op code of a jetton wallet. */
|
|
479
485
|
declare const JETTON_TRANSFER_OP = 260734629;
|
|
480
486
|
/** What one outgoing message does. */
|
|
@@ -553,6 +559,21 @@ type DecodedBody = {
|
|
|
553
559
|
};
|
|
554
560
|
/** Decode a message body cell. */
|
|
555
561
|
declare function decodeBody(body: Cell): DecodedBody;
|
|
562
|
+
/**
|
|
563
|
+
* A base64 BoC as its single root Cell, refused when its layout is one other readers may parse
|
|
564
|
+
* differently from @ton/core: a magic other than the generic one, more than one root, absent cells,
|
|
565
|
+
* or any cell that stores its hashes (with_hashes: @ton/core skips a hash area another reader takes
|
|
566
|
+
* for data), has a level mask, or is exotic. What remains is read the same by every reader, the
|
|
567
|
+
* kit's policy reader included, whatever order the serializer put the cells in (scan 2026-10-27
|
|
568
|
+
* F2, F4). Real provider BoCs order cells differently from @ton/core, so the bytes are not required
|
|
569
|
+
* to round-trip.
|
|
570
|
+
*/
|
|
571
|
+
declare function canonicalBocCell(b64: string, what?: string): Cell;
|
|
572
|
+
/**
|
|
573
|
+
* The body a message is built with: a Cell, a text comment, or a canonical `bodyBoc`. A `body` that is
|
|
574
|
+
* neither a string nor a Cell is refused rather than replaced by `bodyBoc` (scan 2026-10-27 F4).
|
|
575
|
+
*/
|
|
576
|
+
declare function messageBody(tx: TonTransaction): Cell | undefined;
|
|
556
577
|
/** A text comment body (op 0 plus the text), as wallets show it. */
|
|
557
578
|
declare function commentCell(text: string): Cell;
|
|
558
579
|
/** Describe one outgoing message and push its warnings into `warnings`. */
|
|
@@ -723,12 +744,13 @@ declare function tonSignDataDigest(address: TonAddressParts, request: TonSignDat
|
|
|
723
744
|
* once the transaction has passed.
|
|
724
745
|
*/
|
|
725
746
|
declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWalletAccount {
|
|
747
|
+
#private;
|
|
726
748
|
/** seqno and fees come from the network before signing. */
|
|
727
749
|
readonly needsNetwork = true;
|
|
728
750
|
/** Derivation path, `ton-mnemonic`, or `external`. */
|
|
729
751
|
readonly path: string;
|
|
730
|
-
/**
|
|
731
|
-
readonly
|
|
752
|
+
/** What holds the key: `seed`, `key` (one imported key) or `external`. */
|
|
753
|
+
readonly signerKind: Signer['kind'];
|
|
732
754
|
private _readOnly;
|
|
733
755
|
/** `publicKey` is the signer's 32-byte ed25519 key; the V5R1 address derives from it synchronously. */
|
|
734
756
|
constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: TonConfig);
|
|
@@ -766,7 +788,6 @@ declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWall
|
|
|
766
788
|
private assertNoDrain;
|
|
767
789
|
/** The send modes of a prebuilt V5R1 body; an unreadable body is left to the emulation and the node. */
|
|
768
790
|
private bodyModes;
|
|
769
|
-
private signMessages;
|
|
770
791
|
private preflight;
|
|
771
792
|
/** Sign without broadcasting. Returns the external-message BODY as base64 BoC (pass it back to sendTransaction as a Cell). */
|
|
772
793
|
signTransaction(tx: TonSendable, options?: WriteOptions): Promise<string>;
|
|
@@ -818,4 +839,4 @@ declare class WalletManagerTon extends WalletManager<WalletAccountTon, TonConfig
|
|
|
818
839
|
getFeeRates(): Promise<FeeRates>;
|
|
819
840
|
}
|
|
820
841
|
|
|
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 };
|
|
842
|
+
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, canonicalBocCell, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, isAnsweredRefusal, messageBody, parseEmulation, parseTonapiConsequences, parseTonapiRisk, parseTonapiTrace, parseV5R1Body, resolveEmulate, runEmulation, tonCenterEndpoint, tonProofDigest, tonSignDataDigest, v5r1Address, v5r1Code, v5r1ExternalMessage, v5r1PackSigned, v5r1PackUnsigned, v5r1SigningMessage, v5r1StateInit, v5r1WalletId };
|
package/dist/index.d.ts
CHANGED
|
@@ -67,6 +67,12 @@ interface TonConfig {
|
|
|
67
67
|
validUntilSeconds?: number;
|
|
68
68
|
/** Nanotons attached to a jetton transfer on top of `forwardTonAmount` (default 0.05 TON). */
|
|
69
69
|
jettonAttachedValue?: bigint | number | string;
|
|
70
|
+
/**
|
|
71
|
+
* Most nanotons a jetton `transfer()` may attach to the jetton-wallet call, `forwardTonAmount`
|
|
72
|
+
* included (default 1 TON). The contract that receives them is the one the jetton master names,
|
|
73
|
+
* so a fake master gets all of it: the cap bounds what such a call can cost.
|
|
74
|
+
*/
|
|
75
|
+
maxJettonAttachedValue?: bigint | number | string;
|
|
70
76
|
/**
|
|
71
77
|
* 'mainnet' (ton:-239, default) or 'testnet' (ton:-3). Sets the CAIP-2 id, the address flags and the
|
|
72
78
|
* wallet_id network (-239 / -3), so a testnet wallet has its own address and its signed messages are
|
|
@@ -122,8 +128,14 @@ interface TonTransferOptions {
|
|
|
122
128
|
memo?: string;
|
|
123
129
|
/** Jetton only: custom payload cell (rarely needed; e.g. mintless jettons). */
|
|
124
130
|
customPayload?: Cell;
|
|
125
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Jetton only: where excess TON returns (default: this wallet). Another address is refused
|
|
133
|
+
* unless `allowForeignResponseDestination` is set: it receives TON the policies' recipient
|
|
134
|
+
* check never sees.
|
|
135
|
+
*/
|
|
126
136
|
responseDestination?: string;
|
|
137
|
+
/** Jetton only: let `responseDestination` be another address than this wallet. Off by default. */
|
|
138
|
+
allowForeignResponseDestination?: boolean;
|
|
127
139
|
/** Jetton only: query id (default random). */
|
|
128
140
|
queryId?: bigint | number;
|
|
129
141
|
/** Jetton only: nanotons attached to the jetton-wallet call (default config.jettonAttachedValue + forwardTonAmount). */
|
|
@@ -469,12 +481,6 @@ interface ParsedV5R1Body {
|
|
|
469
481
|
/** Parse a signed (or zero-signed) V5R1 external body back into its messages. Returns null for anything else. */
|
|
470
482
|
declare function parseV5R1Body(body: Cell): ParsedV5R1Body | null;
|
|
471
483
|
|
|
472
|
-
/**
|
|
473
|
-
* "What am I signing" for TON — offline. Decodes the messages of a
|
|
474
|
-
* {@link TonSendable} (or a prebuilt V5R1 body) into human-checkable items and
|
|
475
|
-
* flags the classic mistakes before any key is touched.
|
|
476
|
-
*/
|
|
477
|
-
|
|
478
484
|
/** TEP-74 `transfer` op code of a jetton wallet. */
|
|
479
485
|
declare const JETTON_TRANSFER_OP = 260734629;
|
|
480
486
|
/** What one outgoing message does. */
|
|
@@ -553,6 +559,21 @@ type DecodedBody = {
|
|
|
553
559
|
};
|
|
554
560
|
/** Decode a message body cell. */
|
|
555
561
|
declare function decodeBody(body: Cell): DecodedBody;
|
|
562
|
+
/**
|
|
563
|
+
* A base64 BoC as its single root Cell, refused when its layout is one other readers may parse
|
|
564
|
+
* differently from @ton/core: a magic other than the generic one, more than one root, absent cells,
|
|
565
|
+
* or any cell that stores its hashes (with_hashes: @ton/core skips a hash area another reader takes
|
|
566
|
+
* for data), has a level mask, or is exotic. What remains is read the same by every reader, the
|
|
567
|
+
* kit's policy reader included, whatever order the serializer put the cells in (scan 2026-10-27
|
|
568
|
+
* F2, F4). Real provider BoCs order cells differently from @ton/core, so the bytes are not required
|
|
569
|
+
* to round-trip.
|
|
570
|
+
*/
|
|
571
|
+
declare function canonicalBocCell(b64: string, what?: string): Cell;
|
|
572
|
+
/**
|
|
573
|
+
* The body a message is built with: a Cell, a text comment, or a canonical `bodyBoc`. A `body` that is
|
|
574
|
+
* neither a string nor a Cell is refused rather than replaced by `bodyBoc` (scan 2026-10-27 F4).
|
|
575
|
+
*/
|
|
576
|
+
declare function messageBody(tx: TonTransaction): Cell | undefined;
|
|
556
577
|
/** A text comment body (op 0 plus the text), as wallets show it. */
|
|
557
578
|
declare function commentCell(text: string): Cell;
|
|
558
579
|
/** Describe one outgoing message and push its warnings into `warnings`. */
|
|
@@ -723,12 +744,13 @@ declare function tonSignDataDigest(address: TonAddressParts, request: TonSignDat
|
|
|
723
744
|
* once the transaction has passed.
|
|
724
745
|
*/
|
|
725
746
|
declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWalletAccount {
|
|
747
|
+
#private;
|
|
726
748
|
/** seqno and fees come from the network before signing. */
|
|
727
749
|
readonly needsNetwork = true;
|
|
728
750
|
/** Derivation path, `ton-mnemonic`, or `external`. */
|
|
729
751
|
readonly path: string;
|
|
730
|
-
/**
|
|
731
|
-
readonly
|
|
752
|
+
/** What holds the key: `seed`, `key` (one imported key) or `external`. */
|
|
753
|
+
readonly signerKind: Signer['kind'];
|
|
732
754
|
private _readOnly;
|
|
733
755
|
/** `publicKey` is the signer's 32-byte ed25519 key; the V5R1 address derives from it synchronously. */
|
|
734
756
|
constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: TonConfig);
|
|
@@ -766,7 +788,6 @@ declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWall
|
|
|
766
788
|
private assertNoDrain;
|
|
767
789
|
/** The send modes of a prebuilt V5R1 body; an unreadable body is left to the emulation and the node. */
|
|
768
790
|
private bodyModes;
|
|
769
|
-
private signMessages;
|
|
770
791
|
private preflight;
|
|
771
792
|
/** Sign without broadcasting. Returns the external-message BODY as base64 BoC (pass it back to sendTransaction as a Cell). */
|
|
772
793
|
signTransaction(tx: TonSendable, options?: WriteOptions): Promise<string>;
|
|
@@ -818,4 +839,4 @@ declare class WalletManagerTon extends WalletManager<WalletAccountTon, TonConfig
|
|
|
818
839
|
getFeeRates(): Promise<FeeRates>;
|
|
819
840
|
}
|
|
820
841
|
|
|
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 };
|
|
842
|
+
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, canonicalBocCell, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, isAnsweredRefusal, messageBody, 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-ZFENRKRW.js";
|
|
14
14
|
|
|
15
15
|
// src/buffer-global.ts
|
|
16
16
|
import { Buffer } from "buffer";
|
|
@@ -559,6 +559,7 @@ function parseV5R1Body(body) {
|
|
|
559
559
|
}
|
|
560
560
|
|
|
561
561
|
// src/describe.ts
|
|
562
|
+
import { Buffer as Buffer4 } from "buffer";
|
|
562
563
|
import { Address as Address3, Cell as Cell3, beginCell as beginCell2 } from "@ton/core";
|
|
563
564
|
var JETTON_TRANSFER_OP = 260734629;
|
|
564
565
|
var LARGE_FORWARD_NANOTON = 500000000n;
|
|
@@ -618,11 +619,67 @@ function parseTo(to) {
|
|
|
618
619
|
const a = Address3.parse(to);
|
|
619
620
|
return { to: a.toRawString(), bounceable: true, workchain: a.workChain };
|
|
620
621
|
}
|
|
621
|
-
function
|
|
622
|
+
function canonicalBocCell(b64, what = "bodyBoc") {
|
|
623
|
+
if (!/^[A-Za-z0-9+/_-]+={0,2}$/.test(b64)) throw new UnsafeTransactionError("non-canonical-boc", `${what} is not a base64 string.`);
|
|
624
|
+
const bytes = Buffer4.from(b64, "base64");
|
|
625
|
+
const layout = plainBocLayout(bytes);
|
|
626
|
+
if (layout !== null) throw new UnsafeTransactionError("non-canonical-boc", `${what} is not a plain single-root BoC (${layout}), so what was reviewed may not be what is signed.`);
|
|
627
|
+
let roots;
|
|
628
|
+
try {
|
|
629
|
+
roots = Cell3.fromBoc(bytes);
|
|
630
|
+
} catch {
|
|
631
|
+
throw new UnsafeTransactionError("non-canonical-boc", `${what} is not a valid BoC.`);
|
|
632
|
+
}
|
|
633
|
+
if (roots.length !== 1) throw new UnsafeTransactionError("non-canonical-boc", `${what} has ${roots.length} roots.`);
|
|
634
|
+
return roots[0];
|
|
635
|
+
}
|
|
636
|
+
function plainBocLayout(b) {
|
|
637
|
+
if (b.length < 6 || b[0] !== 181 || b[1] !== 238 || b[2] !== 156 || b[3] !== 114) return "not the generic BoC magic";
|
|
638
|
+
const flags = b[4];
|
|
639
|
+
const size = flags & 7;
|
|
640
|
+
const offBytes = b[5];
|
|
641
|
+
if (size < 1 || size > 4 || offBytes < 1 || offBytes > 8) return "bad size fields";
|
|
642
|
+
let i = 6;
|
|
643
|
+
const int = (n) => {
|
|
644
|
+
if (i + n > b.length) throw new RangeError("truncated");
|
|
645
|
+
let v = 0;
|
|
646
|
+
for (let k = 0; k < n; k++) v = v * 256 + b[i++];
|
|
647
|
+
return v;
|
|
648
|
+
};
|
|
649
|
+
try {
|
|
650
|
+
const cells = int(size);
|
|
651
|
+
const roots = int(size);
|
|
652
|
+
const absent = int(size);
|
|
653
|
+
int(offBytes);
|
|
654
|
+
if (roots !== 1) return `${roots} roots`;
|
|
655
|
+
if (absent !== 0) return "absent cells";
|
|
656
|
+
i += roots * size;
|
|
657
|
+
if (flags & 128) i += cells * offBytes;
|
|
658
|
+
for (let c = 0; c < cells; c++) {
|
|
659
|
+
if (i + 2 > b.length) return "truncated";
|
|
660
|
+
const d1 = b[i++];
|
|
661
|
+
const d2 = b[i++];
|
|
662
|
+
if (d1 & 16) return "a cell stores its hashes";
|
|
663
|
+
if (d1 >> 5 !== 0) return "a cell has a level mask";
|
|
664
|
+
if (d1 & 8) return "an exotic cell";
|
|
665
|
+
if ((d1 & 7) > 4) return "a cell with more than 4 refs";
|
|
666
|
+
i += Math.ceil(d2 / 2) + (d1 & 7) * size;
|
|
667
|
+
}
|
|
668
|
+
if (i + (flags & 64 ? 4 : 0) !== b.length) return "trailing or missing bytes";
|
|
669
|
+
} catch {
|
|
670
|
+
return "truncated";
|
|
671
|
+
}
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
function messageBody(tx) {
|
|
622
675
|
if (tx.body instanceof Cell3) return tx.body;
|
|
623
676
|
if (typeof tx.body === "string") return tx.body === "" ? void 0 : commentCell(tx.body);
|
|
624
|
-
if (tx.
|
|
625
|
-
|
|
677
|
+
if (tx.body !== void 0) throw new UnsafeTransactionError("body", "A message body must be a Cell or a string (a text comment).");
|
|
678
|
+
if (tx.bodyBoc !== void 0 && typeof tx.bodyBoc !== "string") throw new UnsafeTransactionError("body", "bodyBoc must be a base64 string.");
|
|
679
|
+
return tx.bodyBoc ? canonicalBocCell(tx.bodyBoc) : void 0;
|
|
680
|
+
}
|
|
681
|
+
function bodyOf(tx) {
|
|
682
|
+
return messageBody(tx);
|
|
626
683
|
}
|
|
627
684
|
function commentCell(text) {
|
|
628
685
|
return beginCell2().storeUint(0, 32).storeStringTail(text).endCell();
|
|
@@ -728,6 +785,8 @@ import { ed25519 } from "@noble/curves/ed25519.js";
|
|
|
728
785
|
import { Address as Address4, Cell as Cell4, beginCell as beginCell3, internal, loadStateInit } from "@ton/core";
|
|
729
786
|
var JETTON_TRANSFER_OP2 = 260734629;
|
|
730
787
|
var DEFAULT_JETTON_ATTACHED = 50000000n;
|
|
788
|
+
var DEFAULT_MAX_JETTON_ATTACHED = 1000000000n;
|
|
789
|
+
var RAW_ADDRESS = /^-?\d+:[0-9a-fA-F]{64}$/;
|
|
731
790
|
var DEFAULT_INDEXER = "https://toncenter.com/api/v3";
|
|
732
791
|
var DEFAULT_VALID_SECONDS = 60;
|
|
733
792
|
var MAX_VALID_SECONDS = 600;
|
|
@@ -829,13 +888,15 @@ var WalletAccountReadOnlyTon = class {
|
|
|
829
888
|
let address;
|
|
830
889
|
let bounceable = true;
|
|
831
890
|
let testOnly;
|
|
832
|
-
if (Address4.isFriendly(to)) {
|
|
891
|
+
if (typeof to === "string" && Address4.isFriendly(to)) {
|
|
833
892
|
const f = Address4.parseFriendly(to);
|
|
834
893
|
address = f.address;
|
|
835
894
|
bounceable = f.isBounceable;
|
|
836
895
|
testOnly = f.isTestOnly;
|
|
837
|
-
} else {
|
|
896
|
+
} else if (typeof to === "string" && RAW_ADDRESS.test(to)) {
|
|
838
897
|
address = Address4.parse(to);
|
|
898
|
+
} else {
|
|
899
|
+
throw new UnsafeTransactionError("address", `${JSON.stringify(to)} is not a TON address in a strict form (raw wc:hex, or a friendly address with its checksum).`);
|
|
839
900
|
}
|
|
840
901
|
if (address.workChain !== 0 && address.workChain !== -1) throw new UnsafeTransactionError("exotic-workchain", `Refusing to send to workchain ${address.workChain}.`);
|
|
841
902
|
const testnet = this._config.network === "testnet";
|
|
@@ -848,7 +909,7 @@ var WalletAccountReadOnlyTon = class {
|
|
|
848
909
|
const value = big(tx.value);
|
|
849
910
|
if (value <= 0n) throw new UnsafeTransactionError("zero-value", "TON message value must be positive.");
|
|
850
911
|
const { address, bounceable } = this.checkedAddress(tx.to);
|
|
851
|
-
const body =
|
|
912
|
+
const body = messageBody(tx);
|
|
852
913
|
const init = this.stateInitOf(tx.stateInit);
|
|
853
914
|
const message = internal({ to: address, value, bounce: tx.bounceable ?? bounceable, ...body ? { body } : {}, ...init ? { init } : {} });
|
|
854
915
|
return { message, ...tx.sendMode !== void 0 ? { mode: tx.sendMode } : {} };
|
|
@@ -858,14 +919,22 @@ var WalletAccountReadOnlyTon = class {
|
|
|
858
919
|
if (amount <= 0n) throw new UnsafeTransactionError("zero-value", "Jetton amount must be positive.");
|
|
859
920
|
const recipient = this.checkedAddress(o.recipient).address;
|
|
860
921
|
const response = o.responseDestination ? this.checkedAddress(o.responseDestination).address : void 0;
|
|
922
|
+
if (response && !response.equals(this._address) && o.allowForeignResponseDestination !== true) {
|
|
923
|
+
throw new UnsafeTransactionError("foreign-response-destination", `The excess TON of this jetton transfer would go to ${response.toString()}, not to this wallet; pass allowForeignResponseDestination to allow it.`);
|
|
924
|
+
}
|
|
925
|
+
const forwardTon = o.forwardTonAmount !== void 0 ? big(o.forwardTonAmount) : 1n;
|
|
926
|
+
const attached = o.attachedValue !== void 0 ? big(o.attachedValue) : (this._config.jettonAttachedValue !== void 0 ? big(this._config.jettonAttachedValue) : DEFAULT_JETTON_ATTACHED) + forwardTon;
|
|
927
|
+
const maxAttached = this._config.maxJettonAttachedValue !== void 0 ? big(this._config.maxJettonAttachedValue) : DEFAULT_MAX_JETTON_ATTACHED;
|
|
928
|
+
if (attached > maxAttached || forwardTon > attached) {
|
|
929
|
+
throw new UnsafeTransactionError("attached-value", `A jetton transfer may attach at most ${maxAttached} nanotons, forwardTonAmount included (asked: ${attached}, forward ${forwardTon}); raise config.maxJettonAttachedValue if this is intended.`);
|
|
930
|
+
}
|
|
861
931
|
const jw = await this.getJettonWalletAddress(o.token);
|
|
862
932
|
await this.jettonWalletData(o.token, jw);
|
|
863
|
-
const forwardTonAmount =
|
|
933
|
+
const forwardTonAmount = forwardTon;
|
|
864
934
|
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.");
|
|
865
935
|
const payload = o.forwardPayload ?? o.memo;
|
|
866
936
|
const forwardPayload = payload === void 0 ? null : typeof payload === "string" ? commentCell(payload) : payload;
|
|
867
937
|
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();
|
|
868
|
-
const attached = o.attachedValue !== void 0 ? big(o.attachedValue) : (this._config.jettonAttachedValue !== void 0 ? big(this._config.jettonAttachedValue) : DEFAULT_JETTON_ATTACHED) + forwardTonAmount;
|
|
869
938
|
return { message: internal({ to: jw, value: attached, bounce: true, body }) };
|
|
870
939
|
}
|
|
871
940
|
toMessages(tx) {
|
|
@@ -982,12 +1051,12 @@ function randomQueryId() {
|
|
|
982
1051
|
|
|
983
1052
|
// src/account.ts
|
|
984
1053
|
import { LocalSigner, feeLimit, requireCurve } from "@anywalletkit/core";
|
|
985
|
-
import { Buffer as
|
|
1054
|
+
import { Buffer as Buffer6 } from "buffer";
|
|
986
1055
|
import { Cell as Cell5 } from "@ton/core";
|
|
987
1056
|
|
|
988
1057
|
// src/tonconnect.ts
|
|
989
1058
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
990
|
-
import { Buffer as
|
|
1059
|
+
import { Buffer as Buffer5 } from "buffer";
|
|
991
1060
|
var utf82 = (s) => new TextEncoder().encode(s);
|
|
992
1061
|
var int32BE = (n) => {
|
|
993
1062
|
const b = new Uint8Array(4);
|
|
@@ -1022,7 +1091,7 @@ function checkCommon(address, domain, timestamp) {
|
|
|
1022
1091
|
function base64Bytes(raw) {
|
|
1023
1092
|
const s = raw.replace(/[\t\n\f\r ]/g, "");
|
|
1024
1093
|
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(s) || s.replace(/=+$/, "").length % 4 === 1) throw new TypeError("signData binary payload must be base64.");
|
|
1025
|
-
return new Uint8Array(
|
|
1094
|
+
return new Uint8Array(Buffer5.from(s, "base64"));
|
|
1026
1095
|
}
|
|
1027
1096
|
function tonProofDigest(address, request) {
|
|
1028
1097
|
checkCommon(address, request.domain, request.timestamp);
|
|
@@ -1056,13 +1125,20 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1056
1125
|
needsNetwork = true;
|
|
1057
1126
|
/** Derivation path, `ton-mnemonic`, or `external`. */
|
|
1058
1127
|
path;
|
|
1059
|
-
/**
|
|
1060
|
-
|
|
1128
|
+
/**
|
|
1129
|
+
* The signer that holds the key, in a private field: not a property of the account, so no code
|
|
1130
|
+
* the account is handed to (a protocol module, a logger) can reach it and sign around the
|
|
1131
|
+
* account's checks (audit 2026-10-29 A1).
|
|
1132
|
+
*/
|
|
1133
|
+
#signer;
|
|
1134
|
+
/** What holds the key: `seed`, `key` (one imported key) or `external`. */
|
|
1135
|
+
signerKind;
|
|
1061
1136
|
_readOnly;
|
|
1062
1137
|
/** `publicKey` is the signer's 32-byte ed25519 key; the V5R1 address derives from it synchronously. */
|
|
1063
1138
|
constructor(signer, publicKey, path, config = {}) {
|
|
1064
1139
|
super(publicKey, config);
|
|
1065
|
-
this
|
|
1140
|
+
this.#signer = requireCurve(signer, "ed25519");
|
|
1141
|
+
this.signerKind = this.#signer.kind;
|
|
1066
1142
|
this.path = path;
|
|
1067
1143
|
}
|
|
1068
1144
|
/** Back-compat: wrap a raw derived key in a {@link LocalSigner} (the account takes ownership; it cannot derive). */
|
|
@@ -1085,7 +1161,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1085
1161
|
async sign(message) {
|
|
1086
1162
|
const bytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
1087
1163
|
if (bytes.length === 32 || carriesKey(bytes, this.publicKey)) throw new MessageIsTransactionError();
|
|
1088
|
-
return toHex(await this
|
|
1164
|
+
return toHex(await this.#signer.sign(bytes, { scheme: "ed25519", context: "ton-message" }));
|
|
1089
1165
|
}
|
|
1090
1166
|
/**
|
|
1091
1167
|
* TON Connect `ton_proof` for this wallet's address: the `proof` object of the connect reply. The
|
|
@@ -1094,20 +1170,20 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1094
1170
|
*/
|
|
1095
1171
|
async signTonProof(request) {
|
|
1096
1172
|
const digest = tonProofDigest(this._address, request);
|
|
1097
|
-
const signature = await this
|
|
1173
|
+
const signature = await this.#signer.sign(digest, { scheme: "ed25519", context: "ton-proof" });
|
|
1098
1174
|
return {
|
|
1099
1175
|
timestamp: request.timestamp,
|
|
1100
1176
|
domain: { lengthBytes: new TextEncoder().encode(request.domain).length, value: request.domain },
|
|
1101
1177
|
payload: request.payload,
|
|
1102
|
-
signature:
|
|
1178
|
+
signature: Buffer6.from(signature).toString("base64")
|
|
1103
1179
|
};
|
|
1104
1180
|
}
|
|
1105
1181
|
/** TON Connect `signData` (text / binary) for this wallet's address: the reply the dApp gets. */
|
|
1106
1182
|
async signTonConnectData(request) {
|
|
1107
1183
|
const digest = tonSignDataDigest(this._address, request);
|
|
1108
|
-
const signature = await this
|
|
1184
|
+
const signature = await this.#signer.sign(digest, { scheme: "ed25519", context: "ton-sign-data" });
|
|
1109
1185
|
return {
|
|
1110
|
-
signature:
|
|
1186
|
+
signature: Buffer6.from(signature).toString("base64"),
|
|
1111
1187
|
address: this._address.toRawString(),
|
|
1112
1188
|
timestamp: request.timestamp,
|
|
1113
1189
|
domain: request.domain,
|
|
@@ -1135,7 +1211,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1135
1211
|
bodyModes(body) {
|
|
1136
1212
|
return parseV5R1Body(body)?.messages.map((m) => m.mode) ?? [];
|
|
1137
1213
|
}
|
|
1138
|
-
async signMessages(messages, limit, op) {
|
|
1214
|
+
async #signMessages(messages, limit, op) {
|
|
1139
1215
|
this.assertNoDrain(messages.map((m) => sendModeOf(m.mode)));
|
|
1140
1216
|
const want = messages.reduce((sum, m) => sum + (m.message.info.type === "internal" ? m.message.info.value.coins : 0n), 0n);
|
|
1141
1217
|
if (want > 0n) {
|
|
@@ -1144,7 +1220,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1144
1220
|
}
|
|
1145
1221
|
const { signing } = await this.signingCell(messages);
|
|
1146
1222
|
const fee = await this.preflight(v5r1PackUnsigned(signing), limit, op, want);
|
|
1147
|
-
const signature = await this
|
|
1223
|
+
const signature = await this.#signer.sign(new Uint8Array(signing.hash()), { scheme: "ed25519", context: "ton-external" });
|
|
1148
1224
|
return { body: v5r1PackSigned(signing, signature), fee };
|
|
1149
1225
|
}
|
|
1150
1226
|
async preflight(body, limit, op, expectedTonOut) {
|
|
@@ -1172,7 +1248,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1172
1248
|
await this.preflight(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1173
1249
|
return tx.toBoc().toString("base64");
|
|
1174
1250
|
}
|
|
1175
|
-
const { body } = await this
|
|
1251
|
+
const { body } = await this.#signMessages(this.toMessages(tx), feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1176
1252
|
return body.toBoc().toString("base64");
|
|
1177
1253
|
}
|
|
1178
1254
|
async broadcast(body) {
|
|
@@ -1191,14 +1267,14 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1191
1267
|
async sendTransaction(tx, options = {}) {
|
|
1192
1268
|
this.requireRpc("send transactions");
|
|
1193
1269
|
if (tx instanceof Cell5) this.assertNoDrain(this.bodyModes(tx));
|
|
1194
|
-
const { body, fee } = tx instanceof Cell5 ? { body: tx, fee: await this.preflight(tx, feeLimit(this._config.transactionMaxFee, options), "transaction") } : await this
|
|
1270
|
+
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");
|
|
1195
1271
|
return { hash: await this.broadcast(body), fee };
|
|
1196
1272
|
}
|
|
1197
1273
|
/** TON (no `token`) or jetton transfer. */
|
|
1198
1274
|
async transfer(o, writeOptions = {}) {
|
|
1199
1275
|
this.requireRpc("transfer tokens");
|
|
1200
1276
|
const message = o.token ? await this.jettonTransferMessage(o) : this.transactionMessage({ to: o.recipient, value: o.amount, ...o.memo !== void 0 ? { body: o.memo } : {} });
|
|
1201
|
-
const { body, fee } = await this
|
|
1277
|
+
const { body, fee } = await this.#signMessages([message], feeLimit(this._config.transferMaxFee, writeOptions), "transfer");
|
|
1202
1278
|
return { hash: await this.broadcast(body), fee };
|
|
1203
1279
|
}
|
|
1204
1280
|
/** The same wallet as a {@link WalletAccountReadOnlyTon}. */
|
|
@@ -1208,7 +1284,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1208
1284
|
}
|
|
1209
1285
|
/** Disposes the signer: a local key is zeroized, an external one is released. */
|
|
1210
1286
|
dispose() {
|
|
1211
|
-
this
|
|
1287
|
+
this.#signer.dispose();
|
|
1212
1288
|
}
|
|
1213
1289
|
};
|
|
1214
1290
|
|
|
@@ -1317,6 +1393,7 @@ export {
|
|
|
1317
1393
|
WalletAccountReadOnlyTon,
|
|
1318
1394
|
WalletAccountTon,
|
|
1319
1395
|
WalletManagerTon,
|
|
1396
|
+
canonicalBocCell,
|
|
1320
1397
|
commentCell,
|
|
1321
1398
|
createTonRpc as createTonClient,
|
|
1322
1399
|
createTonHistory,
|
|
@@ -1334,6 +1411,7 @@ export {
|
|
|
1334
1411
|
mapActions as mapTonapiActions,
|
|
1335
1412
|
mapTonapiEvent,
|
|
1336
1413
|
mapToncenterTransaction,
|
|
1414
|
+
messageBody,
|
|
1337
1415
|
parseEmulation,
|
|
1338
1416
|
parseTonapiConsequences,
|
|
1339
1417
|
parseTonapiRisk,
|