@dynamic-labs/waas-ton 4.51.2 → 4.52.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/package.cjs +1 -1
  3. package/package.js +1 -1
  4. package/package.json +12 -5
  5. package/src/DynamicWaasTonConnectors.cjs +12 -0
  6. package/src/DynamicWaasTonConnectors.d.ts +2 -0
  7. package/src/DynamicWaasTonConnectors.js +8 -0
  8. package/src/connector/DynamicWaasTonConnector.cjs +282 -0
  9. package/src/connector/DynamicWaasTonConnector.d.ts +153 -0
  10. package/src/connector/DynamicWaasTonConnector.js +278 -0
  11. package/src/connector/TonWalletConnector.cjs +41 -0
  12. package/src/connector/TonWalletConnector.d.ts +29 -0
  13. package/src/connector/TonWalletConnector.js +37 -0
  14. package/src/index.cjs +21 -15
  15. package/src/index.d.ts +6 -6
  16. package/src/index.js +12 -3
  17. package/src/signer/DynamicWaasTonSigner.cjs +61 -0
  18. package/src/signer/DynamicWaasTonSigner.d.ts +20 -0
  19. package/src/signer/DynamicWaasTonSigner.js +57 -0
  20. package/src/types/index.cjs +13 -0
  21. package/src/types/index.d.ts +35 -1
  22. package/src/types/index.js +11 -0
  23. package/src/utils/convertSendTransactionRequest/convertSendTransactionRequest.cjs +117 -0
  24. package/src/utils/convertSendTransactionRequest/convertSendTransactionRequest.d.ts +9 -0
  25. package/src/utils/convertSendTransactionRequest/convertSendTransactionRequest.js +113 -0
  26. package/src/utils/convertSendTransactionRequest/index.d.ts +1 -0
  27. package/src/utils/executeTransaction/executeTransaction.cjs +55 -0
  28. package/src/utils/executeTransaction/executeTransaction.d.ts +25 -0
  29. package/src/utils/executeTransaction/executeTransaction.js +51 -0
  30. package/src/utils/extractDisplayInfoFromRequest/extractDisplayInfoFromRequest.cjs +51 -0
  31. package/src/utils/extractDisplayInfoFromRequest/extractDisplayInfoFromRequest.d.ts +18 -0
  32. package/src/utils/extractDisplayInfoFromRequest/extractDisplayInfoFromRequest.js +47 -0
  33. package/src/utils/extractDisplayInfoFromRequest/index.d.ts +1 -0
  34. package/src/utils/generateTonConnectProofHash/generateTonConnectProofHash.cjs +89 -0
  35. package/src/utils/generateTonConnectProofHash/generateTonConnectProofHash.d.ts +24 -0
  36. package/src/utils/generateTonConnectProofHash/generateTonConnectProofHash.js +85 -0
  37. package/src/utils/getJettonWalletAddress/getJettonWalletAddress.cjs +32 -0
  38. package/src/utils/getJettonWalletAddress/getJettonWalletAddress.d.ts +17 -0
  39. package/src/utils/getJettonWalletAddress/getJettonWalletAddress.js +28 -0
  40. package/src/utils/index.d.ts +8 -0
  41. package/src/utils/logger/logger.cjs +4 -3
  42. package/src/utils/logger/logger.js +3 -1
  43. package/src/utils/prepareJettonTransfer/prepareJettonTransfer.cjs +78 -0
  44. package/src/utils/prepareJettonTransfer/prepareJettonTransfer.d.ts +31 -0
  45. package/src/utils/prepareJettonTransfer/prepareJettonTransfer.js +74 -0
  46. package/src/utils/prepareTonTransfer/prepareTonTransfer.cjs +45 -0
  47. package/src/utils/prepareTonTransfer/prepareTonTransfer.d.ts +23 -0
  48. package/src/utils/prepareTonTransfer/prepareTonTransfer.js +41 -0
  49. package/src/utils/prepareTransaction/prepareTransaction.cjs +65 -0
  50. package/src/utils/prepareTransaction/prepareTransaction.d.ts +32 -0
  51. package/src/utils/prepareTransaction/prepareTransaction.js +61 -0
  52. package/src/wallet/WaasTonWallet.cjs +31 -0
  53. package/src/wallet/WaasTonWallet.d.ts +10 -0
  54. package/src/wallet/WaasTonWallet.js +27 -0
@@ -0,0 +1,11 @@
1
+ 'use client'
2
+ /**
3
+ * Network chain identifier for TON
4
+ */
5
+ var CHAIN;
6
+ (function (CHAIN) {
7
+ CHAIN["MAINNET"] = "-239";
8
+ CHAIN["TESTNET"] = "-3";
9
+ })(CHAIN || (CHAIN = {}));
10
+
11
+ export { CHAIN };
@@ -0,0 +1,117 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var ton = require('@ton/ton');
7
+ var core = require('@ton/core');
8
+
9
+ /**
10
+ * Parses a base64 BOC payload into a Cell
11
+ *
12
+ * @param payload - Base64 encoded BOC string
13
+ * @returns Parsed Cell
14
+ */
15
+ const parsePayload = (payload) => {
16
+ if (!payload) {
17
+ return ton.beginCell().endCell();
18
+ }
19
+ try {
20
+ return ton.Cell.fromBase64(payload);
21
+ }
22
+ catch (e) {
23
+ throw new Error(`Invalid payload BOC: ${e instanceof Error ? e.message : String(e)}`);
24
+ }
25
+ };
26
+ /**
27
+ * Parses a base64 BOC stateInit into code and data cells
28
+ *
29
+ * @param stateInit - Base64 encoded BOC string
30
+ * @returns Object with code and data cells, or undefined if no stateInit
31
+ */
32
+ const parseStateInit = (stateInit) => {
33
+ if (!stateInit) {
34
+ return undefined;
35
+ }
36
+ try {
37
+ const stateInitCell = ton.Cell.fromBase64(stateInit);
38
+ const slice = stateInitCell.beginParse();
39
+ slice.skip(2); // skip split_depth and special flags
40
+ return {
41
+ code: slice.loadRef(),
42
+ data: slice.loadRef(),
43
+ };
44
+ }
45
+ catch (e) {
46
+ throw new Error(`Invalid stateInit BOC: ${e instanceof Error ? e.message : String(e)}`);
47
+ }
48
+ };
49
+ /**
50
+ * Determines the bounce flag from address format
51
+ *
52
+ * In base64 user-friendly format:
53
+ * - Bounceable addresses start with: EQ (mainnet) or kQ (testnet)
54
+ * - Non-bounceable addresses start with: UQ (mainnet) or 0Q (testnet)
55
+ * Default to true (bounceable) for safety with smart contracts
56
+ *
57
+ * @param address - TON address string
58
+ * @returns Boolean bounce flag
59
+ */
60
+ // Non-bounceable addresses start with UQ (mainnet) or 0Q (testnet)
61
+ // All other formats (EQ, kQ, raw) default to bounceable
62
+ const determineBounceFlag = (address) => !address.startsWith('UQ') && !address.startsWith('0Q');
63
+ /**
64
+ * Creates an internal message object
65
+ *
66
+ * @param destAddr - Destination address
67
+ * @param amount - Amount in nanotons
68
+ * @param body - Message body cell
69
+ * @param bounce - Bounce flag
70
+ * @param init - Optional state init with code and data
71
+ * @returns Internal message object
72
+ */
73
+ const createInternalMessage = (destAddr, amount, body, bounce, init) => (Object.assign({ body, info: {
74
+ bounce,
75
+ bounced: false,
76
+ createdAt: 0,
77
+ createdLt: BigInt(0),
78
+ dest: destAddr,
79
+ forwardFee: BigInt(0),
80
+ ihrDisabled: true,
81
+ ihrFee: BigInt(0),
82
+ src: null,
83
+ type: 'internal',
84
+ value: { coins: amount },
85
+ } }, (init && { init })));
86
+ /**
87
+ * Creates an OutActionSendMsg from an internal message
88
+ *
89
+ * @param internalMessage - The internal message object
90
+ * @returns OutActionSendMsg action
91
+ */
92
+ const createSendMsgAction = (internalMessage) => ({
93
+ mode: core.SendMode.PAY_GAS_SEPARATELY | core.SendMode.IGNORE_ERRORS,
94
+ outMsg: internalMessage,
95
+ type: 'sendMsg',
96
+ });
97
+ /**
98
+ * Converts a TON Connect SendTransactionRequest to internal actions array
99
+ *
100
+ * @param request - TON Connect transaction request
101
+ * @returns Array of OutActionSendMsg actions
102
+ */
103
+ const convertSendTransactionRequest = (request) => {
104
+ const actions = [];
105
+ for (const msg of request.messages) {
106
+ const destAddr = ton.Address.parse(msg.address);
107
+ const amount = BigInt(msg.amount);
108
+ const body = parsePayload(msg.payload);
109
+ const init = parseStateInit(msg.stateInit);
110
+ const bounce = determineBounceFlag(msg.address);
111
+ const internalMessage = createInternalMessage(destAddr, amount, body, bounce, init);
112
+ actions.push(createSendMsgAction(internalMessage));
113
+ }
114
+ return actions;
115
+ };
116
+
117
+ exports.convertSendTransactionRequest = convertSendTransactionRequest;
@@ -0,0 +1,9 @@
1
+ import { OutActionSendMsg } from '@ton/core';
2
+ import { SendTransactionRequest } from '../../types';
3
+ /**
4
+ * Converts a TON Connect SendTransactionRequest to internal actions array
5
+ *
6
+ * @param request - TON Connect transaction request
7
+ * @returns Array of OutActionSendMsg actions
8
+ */
9
+ export declare const convertSendTransactionRequest: (request: SendTransactionRequest) => OutActionSendMsg[];
@@ -0,0 +1,113 @@
1
+ 'use client'
2
+ import { Address, beginCell, Cell } from '@ton/ton';
3
+ import { SendMode } from '@ton/core';
4
+
5
+ /**
6
+ * Parses a base64 BOC payload into a Cell
7
+ *
8
+ * @param payload - Base64 encoded BOC string
9
+ * @returns Parsed Cell
10
+ */
11
+ const parsePayload = (payload) => {
12
+ if (!payload) {
13
+ return beginCell().endCell();
14
+ }
15
+ try {
16
+ return Cell.fromBase64(payload);
17
+ }
18
+ catch (e) {
19
+ throw new Error(`Invalid payload BOC: ${e instanceof Error ? e.message : String(e)}`);
20
+ }
21
+ };
22
+ /**
23
+ * Parses a base64 BOC stateInit into code and data cells
24
+ *
25
+ * @param stateInit - Base64 encoded BOC string
26
+ * @returns Object with code and data cells, or undefined if no stateInit
27
+ */
28
+ const parseStateInit = (stateInit) => {
29
+ if (!stateInit) {
30
+ return undefined;
31
+ }
32
+ try {
33
+ const stateInitCell = Cell.fromBase64(stateInit);
34
+ const slice = stateInitCell.beginParse();
35
+ slice.skip(2); // skip split_depth and special flags
36
+ return {
37
+ code: slice.loadRef(),
38
+ data: slice.loadRef(),
39
+ };
40
+ }
41
+ catch (e) {
42
+ throw new Error(`Invalid stateInit BOC: ${e instanceof Error ? e.message : String(e)}`);
43
+ }
44
+ };
45
+ /**
46
+ * Determines the bounce flag from address format
47
+ *
48
+ * In base64 user-friendly format:
49
+ * - Bounceable addresses start with: EQ (mainnet) or kQ (testnet)
50
+ * - Non-bounceable addresses start with: UQ (mainnet) or 0Q (testnet)
51
+ * Default to true (bounceable) for safety with smart contracts
52
+ *
53
+ * @param address - TON address string
54
+ * @returns Boolean bounce flag
55
+ */
56
+ // Non-bounceable addresses start with UQ (mainnet) or 0Q (testnet)
57
+ // All other formats (EQ, kQ, raw) default to bounceable
58
+ const determineBounceFlag = (address) => !address.startsWith('UQ') && !address.startsWith('0Q');
59
+ /**
60
+ * Creates an internal message object
61
+ *
62
+ * @param destAddr - Destination address
63
+ * @param amount - Amount in nanotons
64
+ * @param body - Message body cell
65
+ * @param bounce - Bounce flag
66
+ * @param init - Optional state init with code and data
67
+ * @returns Internal message object
68
+ */
69
+ const createInternalMessage = (destAddr, amount, body, bounce, init) => (Object.assign({ body, info: {
70
+ bounce,
71
+ bounced: false,
72
+ createdAt: 0,
73
+ createdLt: BigInt(0),
74
+ dest: destAddr,
75
+ forwardFee: BigInt(0),
76
+ ihrDisabled: true,
77
+ ihrFee: BigInt(0),
78
+ src: null,
79
+ type: 'internal',
80
+ value: { coins: amount },
81
+ } }, (init && { init })));
82
+ /**
83
+ * Creates an OutActionSendMsg from an internal message
84
+ *
85
+ * @param internalMessage - The internal message object
86
+ * @returns OutActionSendMsg action
87
+ */
88
+ const createSendMsgAction = (internalMessage) => ({
89
+ mode: SendMode.PAY_GAS_SEPARATELY | SendMode.IGNORE_ERRORS,
90
+ outMsg: internalMessage,
91
+ type: 'sendMsg',
92
+ });
93
+ /**
94
+ * Converts a TON Connect SendTransactionRequest to internal actions array
95
+ *
96
+ * @param request - TON Connect transaction request
97
+ * @returns Array of OutActionSendMsg actions
98
+ */
99
+ const convertSendTransactionRequest = (request) => {
100
+ const actions = [];
101
+ for (const msg of request.messages) {
102
+ const destAddr = Address.parse(msg.address);
103
+ const amount = BigInt(msg.amount);
104
+ const body = parsePayload(msg.payload);
105
+ const init = parseStateInit(msg.stateInit);
106
+ const bounce = determineBounceFlag(msg.address);
107
+ const internalMessage = createInternalMessage(destAddr, amount, body, bounce, init);
108
+ actions.push(createSendMsgAction(internalMessage));
109
+ }
110
+ return actions;
111
+ };
112
+
113
+ export { convertSendTransactionRequest };
@@ -0,0 +1 @@
1
+ export { convertSendTransactionRequest } from './convertSendTransactionRequest';
@@ -0,0 +1,55 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../_virtual/_tslib.cjs');
7
+ var ton = require('@ton/ton');
8
+ var core = require('@ton/core');
9
+
10
+ /**
11
+ * Executes a TON transaction
12
+ *
13
+ * @param params - Parameters for executing the transaction
14
+ * @returns Transaction execution result with hash
15
+ */
16
+ const executeTransaction = (params) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
17
+ try {
18
+ const signatureBuffer = Buffer.from(params.signature, 'base64');
19
+ if (signatureBuffer.length !== 64) {
20
+ throw new Error(`Invalid signature length: expected 64 bytes, got ${signatureBuffer.length}`);
21
+ }
22
+ // Parse the signing message (without signature)
23
+ const signingMessageCell = ton.Cell.fromBase64(params.transactionData.messageBody);
24
+ // Append signature to tail (v5r1 uses packSignatureToTail)
25
+ const signedMessageBody = ton.beginCell()
26
+ .storeSlice(signingMessageCell.beginParse())
27
+ .storeBuffer(signatureBuffer) // Signature at tail
28
+ .endCell();
29
+ const address = ton.Address.parse(params.transactionData.address);
30
+ // Build external message
31
+ const externalMsg = core.external({
32
+ body: signedMessageBody,
33
+ to: address,
34
+ });
35
+ // Use storeMessage to properly serialize
36
+ const externalMessage = ton.beginCell()
37
+ .store(core.storeMessage(externalMsg, { forceRef: true }))
38
+ .endCell();
39
+ const boc = externalMessage.toBoc();
40
+ yield params.client.sendFile(boc);
41
+ const txHash = externalMessage.hash().toString('hex');
42
+ return {
43
+ success: true,
44
+ transactionHash: txHash,
45
+ };
46
+ }
47
+ catch (error) {
48
+ return {
49
+ error: error instanceof Error ? error.message : String(error),
50
+ success: false,
51
+ };
52
+ }
53
+ });
54
+
55
+ exports.executeTransaction = executeTransaction;
@@ -0,0 +1,25 @@
1
+ import { TonClient } from '@ton/ton';
2
+ import type { TonTransactionData } from '../../types';
3
+ export interface ExecuteTransactionParams {
4
+ /** Generic transaction data */
5
+ transactionData: TonTransactionData;
6
+ /** Signature as base64 */
7
+ signature: string;
8
+ /** TonClient instance */
9
+ client: TonClient;
10
+ }
11
+ export interface ExecuteTransactionResult {
12
+ /** Whether the transaction was sent successfully */
13
+ success: boolean;
14
+ /** Transaction hash (if successful) */
15
+ transactionHash?: string;
16
+ /** Error message (if failed) */
17
+ error?: string;
18
+ }
19
+ /**
20
+ * Executes a TON transaction
21
+ *
22
+ * @param params - Parameters for executing the transaction
23
+ * @returns Transaction execution result with hash
24
+ */
25
+ export declare const executeTransaction: (params: ExecuteTransactionParams) => Promise<ExecuteTransactionResult>;
@@ -0,0 +1,51 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../_virtual/_tslib.js';
3
+ import { Cell, beginCell, Address } from '@ton/ton';
4
+ import { external, storeMessage } from '@ton/core';
5
+
6
+ /**
7
+ * Executes a TON transaction
8
+ *
9
+ * @param params - Parameters for executing the transaction
10
+ * @returns Transaction execution result with hash
11
+ */
12
+ const executeTransaction = (params) => __awaiter(void 0, void 0, void 0, function* () {
13
+ try {
14
+ const signatureBuffer = Buffer.from(params.signature, 'base64');
15
+ if (signatureBuffer.length !== 64) {
16
+ throw new Error(`Invalid signature length: expected 64 bytes, got ${signatureBuffer.length}`);
17
+ }
18
+ // Parse the signing message (without signature)
19
+ const signingMessageCell = Cell.fromBase64(params.transactionData.messageBody);
20
+ // Append signature to tail (v5r1 uses packSignatureToTail)
21
+ const signedMessageBody = beginCell()
22
+ .storeSlice(signingMessageCell.beginParse())
23
+ .storeBuffer(signatureBuffer) // Signature at tail
24
+ .endCell();
25
+ const address = Address.parse(params.transactionData.address);
26
+ // Build external message
27
+ const externalMsg = external({
28
+ body: signedMessageBody,
29
+ to: address,
30
+ });
31
+ // Use storeMessage to properly serialize
32
+ const externalMessage = beginCell()
33
+ .store(storeMessage(externalMsg, { forceRef: true }))
34
+ .endCell();
35
+ const boc = externalMessage.toBoc();
36
+ yield params.client.sendFile(boc);
37
+ const txHash = externalMessage.hash().toString('hex');
38
+ return {
39
+ success: true,
40
+ transactionHash: txHash,
41
+ };
42
+ }
43
+ catch (error) {
44
+ return {
45
+ error: error instanceof Error ? error.message : String(error),
46
+ success: false,
47
+ };
48
+ }
49
+ });
50
+
51
+ export { executeTransaction };
@@ -0,0 +1,51 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var ton = require('@ton/ton');
7
+
8
+ /**
9
+ * Extracts display information from a SendTransactionRequest
10
+ *
11
+ * @param request - TON Connect SendTransactionRequest
12
+ * @returns Display information for UI confirmation
13
+ */
14
+ const extractDisplayInfoFromRequest = (request) => {
15
+ const [firstMessage] = request.messages;
16
+ const displayInfo = {
17
+ recipient: firstMessage.address,
18
+ value: firstMessage.amount,
19
+ };
20
+ // If there is no payload, return the default display info for a simple transfer
21
+ if (!firstMessage.payload) {
22
+ return displayInfo;
23
+ }
24
+ try {
25
+ const payloadCell = ton.Cell.fromBase64(firstMessage.payload);
26
+ const slice = payloadCell.beginParse();
27
+ const opCode = slice.loadUint(32);
28
+ // Check for jetton transfer opcode (0xf8a7ea5)
29
+ if (opCode === 0xf8a7ea5) {
30
+ slice.loadUint(64); // query_id
31
+ const jettonAmount = slice.loadCoins();
32
+ const destination = slice.loadAddress();
33
+ if (!destination) {
34
+ return displayInfo;
35
+ }
36
+ // Override for jetton transfer
37
+ displayInfo.jettonAddress = firstMessage.address;
38
+ displayInfo.jettonAmount = jettonAmount.toString();
39
+ displayInfo.recipient = destination.toString({
40
+ bounceable: false,
41
+ urlSafe: true,
42
+ });
43
+ }
44
+ }
45
+ catch (_) {
46
+ // If parsing fails, keep default values for a simple transfer
47
+ }
48
+ return displayInfo;
49
+ };
50
+
51
+ exports.extractDisplayInfoFromRequest = extractDisplayInfoFromRequest;
@@ -0,0 +1,18 @@
1
+ import { SendTransactionRequest } from '../../types';
2
+ export interface TransactionRequestDisplayInfo {
3
+ /** Primary recipient address */
4
+ recipient: string;
5
+ /** Native TON amount being sent (in nanotons) */
6
+ value?: string;
7
+ /** Jetton wallet address (if this is a jetton transfer) */
8
+ jettonAddress?: string;
9
+ /** Jetton amount being sent (in base units) */
10
+ jettonAmount?: string;
11
+ }
12
+ /**
13
+ * Extracts display information from a SendTransactionRequest
14
+ *
15
+ * @param request - TON Connect SendTransactionRequest
16
+ * @returns Display information for UI confirmation
17
+ */
18
+ export declare const extractDisplayInfoFromRequest: (request: SendTransactionRequest) => TransactionRequestDisplayInfo;
@@ -0,0 +1,47 @@
1
+ 'use client'
2
+ import { Cell } from '@ton/ton';
3
+
4
+ /**
5
+ * Extracts display information from a SendTransactionRequest
6
+ *
7
+ * @param request - TON Connect SendTransactionRequest
8
+ * @returns Display information for UI confirmation
9
+ */
10
+ const extractDisplayInfoFromRequest = (request) => {
11
+ const [firstMessage] = request.messages;
12
+ const displayInfo = {
13
+ recipient: firstMessage.address,
14
+ value: firstMessage.amount,
15
+ };
16
+ // If there is no payload, return the default display info for a simple transfer
17
+ if (!firstMessage.payload) {
18
+ return displayInfo;
19
+ }
20
+ try {
21
+ const payloadCell = Cell.fromBase64(firstMessage.payload);
22
+ const slice = payloadCell.beginParse();
23
+ const opCode = slice.loadUint(32);
24
+ // Check for jetton transfer opcode (0xf8a7ea5)
25
+ if (opCode === 0xf8a7ea5) {
26
+ slice.loadUint(64); // query_id
27
+ const jettonAmount = slice.loadCoins();
28
+ const destination = slice.loadAddress();
29
+ if (!destination) {
30
+ return displayInfo;
31
+ }
32
+ // Override for jetton transfer
33
+ displayInfo.jettonAddress = firstMessage.address;
34
+ displayInfo.jettonAmount = jettonAmount.toString();
35
+ displayInfo.recipient = destination.toString({
36
+ bounceable: false,
37
+ urlSafe: true,
38
+ });
39
+ }
40
+ }
41
+ catch (_) {
42
+ // If parsing fails, keep default values for a simple transfer
43
+ }
44
+ return displayInfo;
45
+ };
46
+
47
+ export { extractDisplayInfoFromRequest };
@@ -0,0 +1 @@
1
+ export * from './extractDisplayInfoFromRequest';
@@ -0,0 +1,89 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../_virtual/_tslib.cjs');
7
+ var crypto = require('@ton/crypto');
8
+ var ton = require('@ton/ton');
9
+
10
+ const TON_PROOF_PREFIX = 'ton-proof-item-v2/';
11
+ const TON_CONNECT_PREFIX = 'ton-connect';
12
+ /**
13
+ * Builds the TON Connect message
14
+ *
15
+ * According to TON Connect spec:
16
+ * message = utf8_encode("ton-proof-item-v2/") ++
17
+ * Address ++
18
+ * AppDomain ++
19
+ * Timestamp ++
20
+ * Payload
21
+ *
22
+ * Where:
23
+ * - Address = workchain (32-bit big-endian) + hash (256-bit)
24
+ * - AppDomain = lengthBytes (32-bit little-endian) + domain value (bytes)
25
+ * - Timestamp = 64-bit little-endian
26
+ * - Payload = payload string (bytes)
27
+ */
28
+ const generateTonConnectProofMessage = (params) => {
29
+ const address = ton.Address.parse(params.address);
30
+ // Validate that lengthBytes matches the actual byte length of domain value
31
+ const domainBytes = Buffer.from(params.domain.value);
32
+ const actualLengthBytes = domainBytes.length;
33
+ if (params.domain.lengthBytes !== actualLengthBytes) {
34
+ throw new Error(`Domain lengthBytes mismatch: provided ${params.domain.lengthBytes}, actual ${actualLengthBytes}`);
35
+ }
36
+ // Workchain (32-bit big-endian)
37
+ const wc = Buffer.alloc(4);
38
+ wc.writeUInt32BE(address.workChain, 0);
39
+ // Timestamp (64-bit little-endian)
40
+ const ts = Buffer.alloc(8);
41
+ ts.writeBigUInt64LE(BigInt(params.timestamp), 0);
42
+ // Domain length (32-bit little-endian)
43
+ const dl = Buffer.alloc(4);
44
+ dl.writeUInt32LE(params.domain.lengthBytes, 0);
45
+ // Concatenate all parts
46
+ return Buffer.concat([
47
+ Buffer.from(TON_PROOF_PREFIX),
48
+ wc,
49
+ address.hash,
50
+ dl,
51
+ domainBytes,
52
+ ts,
53
+ Buffer.from(params.payload),
54
+ ]);
55
+ };
56
+ /**
57
+ * Generates the hash that needs to be signed by the private key for TON Connect proof
58
+ *
59
+ * The signature process:
60
+ * 1. Build the message: ton-proof-item-v2/ + Address + AppDomain + Timestamp + Payload
61
+ * 2. Hash the message: sha256(message)
62
+ * 3. Build full message: 0xffff + "ton-connect" + sha256(message)
63
+ * 4. Hash again: sha256(full message) - This is what needs to be signed
64
+ *
65
+ * @param params - Parameters for generating the TON Connect proof hash
66
+ * @returns The hash as hex string that needs to be signed
67
+ */
68
+ const generateTonConnectProofHash = (params) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
69
+ // 1. Build the message
70
+ const message = generateTonConnectProofMessage({
71
+ address: params.address,
72
+ domain: params.domain,
73
+ payload: params.payload,
74
+ timestamp: params.timestamp,
75
+ });
76
+ // 2. Hash the message
77
+ const messageHash = Buffer.from((yield crypto.sha256(message)));
78
+ // 3. Build the full message for signing
79
+ const fullMsg = Buffer.concat([
80
+ Buffer.from([0xff, 0xff]),
81
+ Buffer.from(TON_CONNECT_PREFIX),
82
+ messageHash,
83
+ ]);
84
+ // Step 4: Hash again
85
+ const hash = Buffer.from((yield crypto.sha256(fullMsg)));
86
+ return hash.toString('hex');
87
+ });
88
+
89
+ exports.generateTonConnectProofHash = generateTonConnectProofHash;
@@ -0,0 +1,24 @@
1
+ import type { TonConnectDomain } from '../../types';
2
+ export interface GenerateTonConnectProofHashParams {
3
+ /** Wallet address string */
4
+ address: string;
5
+ /** Domain information for TON Connect */
6
+ domain: TonConnectDomain;
7
+ /** Unix timestamp in seconds */
8
+ timestamp: number;
9
+ /** Payload string to include in the proof */
10
+ payload: string;
11
+ }
12
+ /**
13
+ * Generates the hash that needs to be signed by the private key for TON Connect proof
14
+ *
15
+ * The signature process:
16
+ * 1. Build the message: ton-proof-item-v2/ + Address + AppDomain + Timestamp + Payload
17
+ * 2. Hash the message: sha256(message)
18
+ * 3. Build full message: 0xffff + "ton-connect" + sha256(message)
19
+ * 4. Hash again: sha256(full message) - This is what needs to be signed
20
+ *
21
+ * @param params - Parameters for generating the TON Connect proof hash
22
+ * @returns The hash as hex string that needs to be signed
23
+ */
24
+ export declare const generateTonConnectProofHash: (params: GenerateTonConnectProofHashParams) => Promise<string>;