@anywalletkit/wallet-ton 0.3.1 → 0.4.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 +92 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -9
- package/dist/index.d.ts +30 -9
- package/dist/index.js +89 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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,6 +744,7 @@ 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`. */
|
|
@@ -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,6 +744,7 @@ 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`. */
|
|
@@ -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);
|
|
@@ -1099,7 +1168,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1099
1168
|
timestamp: request.timestamp,
|
|
1100
1169
|
domain: { lengthBytes: new TextEncoder().encode(request.domain).length, value: request.domain },
|
|
1101
1170
|
payload: request.payload,
|
|
1102
|
-
signature:
|
|
1171
|
+
signature: Buffer6.from(signature).toString("base64")
|
|
1103
1172
|
};
|
|
1104
1173
|
}
|
|
1105
1174
|
/** TON Connect `signData` (text / binary) for this wallet's address: the reply the dApp gets. */
|
|
@@ -1107,7 +1176,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1107
1176
|
const digest = tonSignDataDigest(this._address, request);
|
|
1108
1177
|
const signature = await this.signer.sign(digest, { scheme: "ed25519", context: "ton-sign-data" });
|
|
1109
1178
|
return {
|
|
1110
|
-
signature:
|
|
1179
|
+
signature: Buffer6.from(signature).toString("base64"),
|
|
1111
1180
|
address: this._address.toRawString(),
|
|
1112
1181
|
timestamp: request.timestamp,
|
|
1113
1182
|
domain: request.domain,
|
|
@@ -1135,7 +1204,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1135
1204
|
bodyModes(body) {
|
|
1136
1205
|
return parseV5R1Body(body)?.messages.map((m) => m.mode) ?? [];
|
|
1137
1206
|
}
|
|
1138
|
-
async signMessages(messages, limit, op) {
|
|
1207
|
+
async #signMessages(messages, limit, op) {
|
|
1139
1208
|
this.assertNoDrain(messages.map((m) => sendModeOf(m.mode)));
|
|
1140
1209
|
const want = messages.reduce((sum, m) => sum + (m.message.info.type === "internal" ? m.message.info.value.coins : 0n), 0n);
|
|
1141
1210
|
if (want > 0n) {
|
|
@@ -1172,7 +1241,7 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1172
1241
|
await this.preflight(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1173
1242
|
return tx.toBoc().toString("base64");
|
|
1174
1243
|
}
|
|
1175
|
-
const { body } = await this
|
|
1244
|
+
const { body } = await this.#signMessages(this.toMessages(tx), feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1176
1245
|
return body.toBoc().toString("base64");
|
|
1177
1246
|
}
|
|
1178
1247
|
async broadcast(body) {
|
|
@@ -1191,14 +1260,14 @@ var WalletAccountTon = class _WalletAccountTon extends WalletAccountReadOnlyTon
|
|
|
1191
1260
|
async sendTransaction(tx, options = {}) {
|
|
1192
1261
|
this.requireRpc("send transactions");
|
|
1193
1262
|
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
|
|
1263
|
+
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
1264
|
return { hash: await this.broadcast(body), fee };
|
|
1196
1265
|
}
|
|
1197
1266
|
/** TON (no `token`) or jetton transfer. */
|
|
1198
1267
|
async transfer(o, writeOptions = {}) {
|
|
1199
1268
|
this.requireRpc("transfer tokens");
|
|
1200
1269
|
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
|
|
1270
|
+
const { body, fee } = await this.#signMessages([message], feeLimit(this._config.transferMaxFee, writeOptions), "transfer");
|
|
1202
1271
|
return { hash: await this.broadcast(body), fee };
|
|
1203
1272
|
}
|
|
1204
1273
|
/** The same wallet as a {@link WalletAccountReadOnlyTon}. */
|
|
@@ -1317,6 +1386,7 @@ export {
|
|
|
1317
1386
|
WalletAccountReadOnlyTon,
|
|
1318
1387
|
WalletAccountTon,
|
|
1319
1388
|
WalletManagerTon,
|
|
1389
|
+
canonicalBocCell,
|
|
1320
1390
|
commentCell,
|
|
1321
1391
|
createTonRpc as createTonClient,
|
|
1322
1392
|
createTonHistory,
|
|
@@ -1334,6 +1404,7 @@ export {
|
|
|
1334
1404
|
mapActions as mapTonapiActions,
|
|
1335
1405
|
mapTonapiEvent,
|
|
1336
1406
|
mapToncenterTransaction,
|
|
1407
|
+
messageBody,
|
|
1337
1408
|
parseEmulation,
|
|
1338
1409
|
parseTonapiConsequences,
|
|
1339
1410
|
parseTonapiRisk,
|