@dynamic-labs/waas-ton 4.51.0 → 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.
- package/CHANGELOG.md +6619 -0
- package/LICENSE +21 -0
- package/_virtual/_tslib.cjs +36 -0
- package/_virtual/_tslib.js +32 -0
- package/package.cjs +8 -0
- package/package.js +4 -0
- package/package.json +13 -6
- package/src/DynamicWaasTonConnectors.cjs +12 -0
- package/src/DynamicWaasTonConnectors.d.ts +2 -0
- package/src/DynamicWaasTonConnectors.js +8 -0
- package/src/connector/DynamicWaasTonConnector.cjs +282 -0
- package/src/connector/DynamicWaasTonConnector.d.ts +153 -0
- package/src/connector/DynamicWaasTonConnector.js +278 -0
- package/src/connector/TonWalletConnector.cjs +41 -0
- package/src/connector/TonWalletConnector.d.ts +29 -0
- package/src/connector/TonWalletConnector.js +37 -0
- package/src/index.cjs +34 -0
- package/src/index.d.ts +7 -0
- package/src/index.js +19 -0
- package/src/signer/DynamicWaasTonSigner.cjs +61 -0
- package/src/signer/DynamicWaasTonSigner.d.ts +20 -0
- package/src/signer/DynamicWaasTonSigner.js +57 -0
- package/src/types/index.cjs +13 -0
- package/src/types/index.d.ts +71 -0
- package/src/types/index.js +11 -0
- package/src/utils/convertSendTransactionRequest/convertSendTransactionRequest.cjs +117 -0
- package/src/utils/convertSendTransactionRequest/convertSendTransactionRequest.d.ts +9 -0
- package/src/utils/convertSendTransactionRequest/convertSendTransactionRequest.js +113 -0
- package/src/utils/convertSendTransactionRequest/index.d.ts +1 -0
- package/src/utils/executeTransaction/executeTransaction.cjs +55 -0
- package/src/utils/executeTransaction/executeTransaction.d.ts +25 -0
- package/src/utils/executeTransaction/executeTransaction.js +51 -0
- package/src/utils/extractDisplayInfoFromRequest/extractDisplayInfoFromRequest.cjs +51 -0
- package/src/utils/extractDisplayInfoFromRequest/extractDisplayInfoFromRequest.d.ts +18 -0
- package/src/utils/extractDisplayInfoFromRequest/extractDisplayInfoFromRequest.js +47 -0
- package/src/utils/extractDisplayInfoFromRequest/index.d.ts +1 -0
- package/src/utils/generateTonConnectProofHash/generateTonConnectProofHash.cjs +89 -0
- package/src/utils/generateTonConnectProofHash/generateTonConnectProofHash.d.ts +24 -0
- package/src/utils/generateTonConnectProofHash/generateTonConnectProofHash.js +85 -0
- package/src/utils/getJettonWalletAddress/getJettonWalletAddress.cjs +32 -0
- package/src/utils/getJettonWalletAddress/getJettonWalletAddress.d.ts +17 -0
- package/src/utils/getJettonWalletAddress/getJettonWalletAddress.js +28 -0
- package/src/utils/getWalletSeqno/getWalletSeqno.cjs +22 -0
- package/src/utils/getWalletSeqno/getWalletSeqno.d.ts +9 -0
- package/src/utils/getWalletSeqno/getWalletSeqno.js +18 -0
- package/src/utils/index.d.ts +10 -0
- package/src/utils/logger/logger.cjs +14 -0
- package/src/utils/logger/logger.d.ts +3 -0
- package/src/utils/logger/logger.js +7 -0
- package/src/utils/prepareJettonTransfer/prepareJettonTransfer.cjs +78 -0
- package/src/utils/prepareJettonTransfer/prepareJettonTransfer.d.ts +31 -0
- package/src/utils/prepareJettonTransfer/prepareJettonTransfer.js +74 -0
- package/src/utils/prepareTonTransfer/prepareTonTransfer.cjs +45 -0
- package/src/utils/prepareTonTransfer/prepareTonTransfer.d.ts +23 -0
- package/src/utils/prepareTonTransfer/prepareTonTransfer.js +41 -0
- package/src/utils/prepareTransaction/prepareTransaction.cjs +65 -0
- package/src/utils/prepareTransaction/prepareTransaction.d.ts +32 -0
- package/src/utils/prepareTransaction/prepareTransaction.js +61 -0
- package/src/wallet/WaasTonWallet.cjs +31 -0
- package/src/wallet/WaasTonWallet.d.ts +10 -0
- package/src/wallet/WaasTonWallet.js +27 -0
- package/.eslintrc.json +0 -33
- package/jest.config.ts +0 -29
- package/project.json +0 -47
- package/rollup.config.cjs +0 -7
- package/src/index.ts +0 -18
- package/src/types/index.ts +0 -39
- package/src/utils/index.ts +0 -1
- package/src/utils/logger/logger.spec.ts +0 -7
- package/src/utils/logger/logger.ts +0 -6
- package/test/mocks/browserWalletClientMock.ts +0 -38
- package/test/setupAfterEnv.config.ts +0 -7
- package/tsconfig.json +0 -23
- package/tsconfig.lib.json +0 -10
- package/tsconfig.spec.json +0 -14
|
@@ -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>;
|