@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.
- package/CHANGELOG.md +9 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +12 -5
- 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 +21 -15
- package/src/index.d.ts +6 -6
- package/src/index.js +12 -3
- 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 +35 -1
- 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/index.d.ts +8 -0
- package/src/utils/logger/logger.cjs +4 -3
- package/src/utils/logger/logger.js +3 -1
- 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
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { sha256 } from '@ton/crypto';
|
|
4
|
+
import { Address } from '@ton/ton';
|
|
5
|
+
|
|
6
|
+
const TON_PROOF_PREFIX = 'ton-proof-item-v2/';
|
|
7
|
+
const TON_CONNECT_PREFIX = 'ton-connect';
|
|
8
|
+
/**
|
|
9
|
+
* Builds the TON Connect message
|
|
10
|
+
*
|
|
11
|
+
* According to TON Connect spec:
|
|
12
|
+
* message = utf8_encode("ton-proof-item-v2/") ++
|
|
13
|
+
* Address ++
|
|
14
|
+
* AppDomain ++
|
|
15
|
+
* Timestamp ++
|
|
16
|
+
* Payload
|
|
17
|
+
*
|
|
18
|
+
* Where:
|
|
19
|
+
* - Address = workchain (32-bit big-endian) + hash (256-bit)
|
|
20
|
+
* - AppDomain = lengthBytes (32-bit little-endian) + domain value (bytes)
|
|
21
|
+
* - Timestamp = 64-bit little-endian
|
|
22
|
+
* - Payload = payload string (bytes)
|
|
23
|
+
*/
|
|
24
|
+
const generateTonConnectProofMessage = (params) => {
|
|
25
|
+
const address = Address.parse(params.address);
|
|
26
|
+
// Validate that lengthBytes matches the actual byte length of domain value
|
|
27
|
+
const domainBytes = Buffer.from(params.domain.value);
|
|
28
|
+
const actualLengthBytes = domainBytes.length;
|
|
29
|
+
if (params.domain.lengthBytes !== actualLengthBytes) {
|
|
30
|
+
throw new Error(`Domain lengthBytes mismatch: provided ${params.domain.lengthBytes}, actual ${actualLengthBytes}`);
|
|
31
|
+
}
|
|
32
|
+
// Workchain (32-bit big-endian)
|
|
33
|
+
const wc = Buffer.alloc(4);
|
|
34
|
+
wc.writeUInt32BE(address.workChain, 0);
|
|
35
|
+
// Timestamp (64-bit little-endian)
|
|
36
|
+
const ts = Buffer.alloc(8);
|
|
37
|
+
ts.writeBigUInt64LE(BigInt(params.timestamp), 0);
|
|
38
|
+
// Domain length (32-bit little-endian)
|
|
39
|
+
const dl = Buffer.alloc(4);
|
|
40
|
+
dl.writeUInt32LE(params.domain.lengthBytes, 0);
|
|
41
|
+
// Concatenate all parts
|
|
42
|
+
return Buffer.concat([
|
|
43
|
+
Buffer.from(TON_PROOF_PREFIX),
|
|
44
|
+
wc,
|
|
45
|
+
address.hash,
|
|
46
|
+
dl,
|
|
47
|
+
domainBytes,
|
|
48
|
+
ts,
|
|
49
|
+
Buffer.from(params.payload),
|
|
50
|
+
]);
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Generates the hash that needs to be signed by the private key for TON Connect proof
|
|
54
|
+
*
|
|
55
|
+
* The signature process:
|
|
56
|
+
* 1. Build the message: ton-proof-item-v2/ + Address + AppDomain + Timestamp + Payload
|
|
57
|
+
* 2. Hash the message: sha256(message)
|
|
58
|
+
* 3. Build full message: 0xffff + "ton-connect" + sha256(message)
|
|
59
|
+
* 4. Hash again: sha256(full message) - This is what needs to be signed
|
|
60
|
+
*
|
|
61
|
+
* @param params - Parameters for generating the TON Connect proof hash
|
|
62
|
+
* @returns The hash as hex string that needs to be signed
|
|
63
|
+
*/
|
|
64
|
+
const generateTonConnectProofHash = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
// 1. Build the message
|
|
66
|
+
const message = generateTonConnectProofMessage({
|
|
67
|
+
address: params.address,
|
|
68
|
+
domain: params.domain,
|
|
69
|
+
payload: params.payload,
|
|
70
|
+
timestamp: params.timestamp,
|
|
71
|
+
});
|
|
72
|
+
// 2. Hash the message
|
|
73
|
+
const messageHash = Buffer.from((yield sha256(message)));
|
|
74
|
+
// 3. Build the full message for signing
|
|
75
|
+
const fullMsg = Buffer.concat([
|
|
76
|
+
Buffer.from([0xff, 0xff]),
|
|
77
|
+
Buffer.from(TON_CONNECT_PREFIX),
|
|
78
|
+
messageHash,
|
|
79
|
+
]);
|
|
80
|
+
// Step 4: Hash again
|
|
81
|
+
const hash = Buffer.from((yield sha256(fullMsg)));
|
|
82
|
+
return hash.toString('hex');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export { generateTonConnectProofHash };
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Derives a jetton wallet address for a given owner by calling
|
|
11
|
+
* the get_wallet_address method on the jetton master contract
|
|
12
|
+
*
|
|
13
|
+
* @param params - Parameters for getting jetton wallet address
|
|
14
|
+
* @returns Jetton wallet address for the owner
|
|
15
|
+
*/
|
|
16
|
+
const getJettonWalletAddress = (params) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const { jettonMasterAddress, ownerAddress, client } = params;
|
|
18
|
+
const masterAddress = ton.Address.parse(jettonMasterAddress);
|
|
19
|
+
const owner = ton.Address.parse(ownerAddress);
|
|
20
|
+
const ownerCell = ton.beginCell().storeAddress(owner).endCell();
|
|
21
|
+
const result = yield client.runMethod(masterAddress, 'get_wallet_address', [
|
|
22
|
+
{ cell: ownerCell, type: 'slice' },
|
|
23
|
+
]);
|
|
24
|
+
const jettonWalletAddress = result.stack.readAddress();
|
|
25
|
+
return jettonWalletAddress.toString({
|
|
26
|
+
bounceable: true,
|
|
27
|
+
testOnly: false,
|
|
28
|
+
urlSafe: true,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
exports.getJettonWalletAddress = getJettonWalletAddress;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TonClient } from '@ton/ton';
|
|
2
|
+
export interface GetJettonWalletAddressParams {
|
|
3
|
+
/** Jetton master contract address */
|
|
4
|
+
jettonMasterAddress: string;
|
|
5
|
+
/** Owner's wallet address */
|
|
6
|
+
ownerAddress: string;
|
|
7
|
+
/** TonClient instance */
|
|
8
|
+
client: TonClient;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Derives a jetton wallet address for a given owner by calling
|
|
12
|
+
* the get_wallet_address method on the jetton master contract
|
|
13
|
+
*
|
|
14
|
+
* @param params - Parameters for getting jetton wallet address
|
|
15
|
+
* @returns Jetton wallet address for the owner
|
|
16
|
+
*/
|
|
17
|
+
export declare const getJettonWalletAddress: (params: GetJettonWalletAddressParams) => Promise<string>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { Address, beginCell } from '@ton/ton';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Derives a jetton wallet address for a given owner by calling
|
|
7
|
+
* the get_wallet_address method on the jetton master contract
|
|
8
|
+
*
|
|
9
|
+
* @param params - Parameters for getting jetton wallet address
|
|
10
|
+
* @returns Jetton wallet address for the owner
|
|
11
|
+
*/
|
|
12
|
+
const getJettonWalletAddress = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const { jettonMasterAddress, ownerAddress, client } = params;
|
|
14
|
+
const masterAddress = Address.parse(jettonMasterAddress);
|
|
15
|
+
const owner = Address.parse(ownerAddress);
|
|
16
|
+
const ownerCell = beginCell().storeAddress(owner).endCell();
|
|
17
|
+
const result = yield client.runMethod(masterAddress, 'get_wallet_address', [
|
|
18
|
+
{ cell: ownerCell, type: 'slice' },
|
|
19
|
+
]);
|
|
20
|
+
const jettonWalletAddress = result.stack.readAddress();
|
|
21
|
+
return jettonWalletAddress.toString({
|
|
22
|
+
bounceable: true,
|
|
23
|
+
testOnly: false,
|
|
24
|
+
urlSafe: true,
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export { getJettonWalletAddress };
|
package/src/utils/index.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
export * from './prepareTransaction/prepareTransaction';
|
|
2
|
+
export * from './generateTonConnectProofHash/generateTonConnectProofHash';
|
|
3
|
+
export * from './prepareTonTransfer/prepareTonTransfer';
|
|
4
|
+
export * from './prepareJettonTransfer/prepareJettonTransfer';
|
|
5
|
+
export * from './getJettonWalletAddress/getJettonWalletAddress';
|
|
1
6
|
export * from './getWalletSeqno/getWalletSeqno';
|
|
7
|
+
export * from './executeTransaction/executeTransaction';
|
|
8
|
+
export * from './extractDisplayInfoFromRequest/extractDisplayInfoFromRequest';
|
|
9
|
+
export * from './convertSendTransactionRequest/convertSendTransactionRequest';
|
|
2
10
|
export * from './logger/logger';
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
|
-
var logger = require('@dynamic-labs/logger');
|
|
6
|
+
var logger$1 = require('@dynamic-labs/logger');
|
|
7
7
|
|
|
8
|
-
new logger.Logger('@dynamic-labs/waas-ton');
|
|
8
|
+
const logger = new logger$1.Logger('@dynamic-labs/waas-ton');
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, 'Logger', {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return logger.Logger; }
|
|
12
|
+
get: function () { return logger$1.Logger; }
|
|
13
13
|
});
|
|
14
|
+
exports.logger = logger;
|
|
@@ -0,0 +1,78 @@
|
|
|
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 index = require('../../types/index.cjs');
|
|
9
|
+
var getJettonWalletAddress = require('../getJettonWalletAddress/getJettonWalletAddress.cjs');
|
|
10
|
+
|
|
11
|
+
const DEFAULT_JETTON_GAS = BigInt(50000000);
|
|
12
|
+
/**
|
|
13
|
+
* Prepares a jetton (non-native token) transfer transaction
|
|
14
|
+
*
|
|
15
|
+
* @param params - Jetton transfer parameters
|
|
16
|
+
* @returns TON Connect SendTransactionRequest
|
|
17
|
+
*/
|
|
18
|
+
const prepareJettonTransfer = (params) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
const { walletAddress, jettonMasterAddress, recipientAddress, jettonAmount, forwardTonAmount, client, forwardPayload = '', timeout = 60, gasAmount = DEFAULT_JETTON_GAS, network = index.CHAIN.MAINNET, } = params;
|
|
20
|
+
const validUntil = Math.floor(Date.now() / 1000) + timeout;
|
|
21
|
+
const jettonWalletAddress = yield getJettonWalletAddress.getJettonWalletAddress({
|
|
22
|
+
client,
|
|
23
|
+
jettonMasterAddress,
|
|
24
|
+
ownerAddress: walletAddress,
|
|
25
|
+
});
|
|
26
|
+
const jettonWalletAddr = ton.Address.parse(jettonWalletAddress);
|
|
27
|
+
const recipientAddr = ton.Address.parse(recipientAddress);
|
|
28
|
+
const walletAddr = ton.Address.parse(walletAddress);
|
|
29
|
+
const isTestnet = network === index.CHAIN.TESTNET;
|
|
30
|
+
// Build jetton transfer payload
|
|
31
|
+
// Jetton transfer message format (TEP-74):
|
|
32
|
+
// transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16)
|
|
33
|
+
// destination:MsgAddress response_destination:MsgAddress
|
|
34
|
+
// custom_payload:(Maybe ^Cell) forward_ton_amount:(VarUInteger 16)
|
|
35
|
+
// forward_payload:(Either Cell ^Cell) = InternalMsgBody;
|
|
36
|
+
const forwardPayloadCell = forwardPayload
|
|
37
|
+
? ton.beginCell()
|
|
38
|
+
.storeUint(0, 32) // text comment opcode
|
|
39
|
+
.storeStringTail(forwardPayload)
|
|
40
|
+
.endCell()
|
|
41
|
+
: ton.beginCell().endCell(); // empty cell
|
|
42
|
+
const jettonTransferBody = ton.beginCell()
|
|
43
|
+
.storeUint(0xf8a7ea5, 32) // jetton transfer op code
|
|
44
|
+
.storeUint(0, 64) // query_id (use 0 or timestamp)
|
|
45
|
+
.storeCoins(jettonAmount) // amount of jettons to transfer
|
|
46
|
+
.storeAddress(recipientAddr) // destination address
|
|
47
|
+
.storeAddress(walletAddr) // response_destination (excess TON goes here)
|
|
48
|
+
.storeBit(0) // custom_payload (null)
|
|
49
|
+
.storeCoins(forwardTonAmount) // forward_ton_amount
|
|
50
|
+
.storeBit(0) // forward_payload in this slice (not separate cell)
|
|
51
|
+
.storeSlice(forwardPayloadCell.beginParse()) // forward_payload content
|
|
52
|
+
.endCell();
|
|
53
|
+
// Total TON = forwardTonAmount + gas for the jetton transfer operation
|
|
54
|
+
const totalAmount = forwardTonAmount + gasAmount;
|
|
55
|
+
// Create TON Connect compatible message
|
|
56
|
+
const message = {
|
|
57
|
+
address: jettonWalletAddr.toString({
|
|
58
|
+
bounceable: true,
|
|
59
|
+
testOnly: isTestnet,
|
|
60
|
+
urlSafe: true,
|
|
61
|
+
}),
|
|
62
|
+
amount: totalAmount.toString(),
|
|
63
|
+
payload: jettonTransferBody.toBoc().toString('base64'),
|
|
64
|
+
};
|
|
65
|
+
const request = {
|
|
66
|
+
from: walletAddr.toString({
|
|
67
|
+
bounceable: false,
|
|
68
|
+
testOnly: isTestnet,
|
|
69
|
+
urlSafe: true,
|
|
70
|
+
}),
|
|
71
|
+
messages: [message],
|
|
72
|
+
network,
|
|
73
|
+
validUntil,
|
|
74
|
+
};
|
|
75
|
+
return request;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
exports.prepareJettonTransfer = prepareJettonTransfer;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { TonClient } from '@ton/ton';
|
|
2
|
+
import { CHAIN, SendTransactionRequest } from '../../types';
|
|
3
|
+
export interface PrepareJettonTransferParams {
|
|
4
|
+
/** Sender wallet address */
|
|
5
|
+
walletAddress: string;
|
|
6
|
+
/** Jetton master contract address */
|
|
7
|
+
jettonMasterAddress: string;
|
|
8
|
+
/** Recipient's main wallet address */
|
|
9
|
+
recipientAddress: string;
|
|
10
|
+
/** Amount of jettons in base units (bigint) */
|
|
11
|
+
jettonAmount: bigint;
|
|
12
|
+
/** TON amount to forward with notification */
|
|
13
|
+
forwardTonAmount: bigint;
|
|
14
|
+
/** TonClient instance */
|
|
15
|
+
client: TonClient;
|
|
16
|
+
/** Optional comment/memo */
|
|
17
|
+
forwardPayload?: string;
|
|
18
|
+
/** Network (MAINNET or TESTNET) */
|
|
19
|
+
network?: CHAIN;
|
|
20
|
+
/** Message timeout in seconds (default: 60) */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
/** Gas amount in nanotons for the jetton transfer */
|
|
23
|
+
gasAmount?: bigint;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Prepares a jetton (non-native token) transfer transaction
|
|
27
|
+
*
|
|
28
|
+
* @param params - Jetton transfer parameters
|
|
29
|
+
* @returns TON Connect SendTransactionRequest
|
|
30
|
+
*/
|
|
31
|
+
export declare const prepareJettonTransfer: (params: PrepareJettonTransferParams) => Promise<SendTransactionRequest>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { Address, beginCell } from '@ton/ton';
|
|
4
|
+
import { CHAIN } from '../../types/index.js';
|
|
5
|
+
import { getJettonWalletAddress } from '../getJettonWalletAddress/getJettonWalletAddress.js';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_JETTON_GAS = BigInt(50000000);
|
|
8
|
+
/**
|
|
9
|
+
* Prepares a jetton (non-native token) transfer transaction
|
|
10
|
+
*
|
|
11
|
+
* @param params - Jetton transfer parameters
|
|
12
|
+
* @returns TON Connect SendTransactionRequest
|
|
13
|
+
*/
|
|
14
|
+
const prepareJettonTransfer = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
const { walletAddress, jettonMasterAddress, recipientAddress, jettonAmount, forwardTonAmount, client, forwardPayload = '', timeout = 60, gasAmount = DEFAULT_JETTON_GAS, network = CHAIN.MAINNET, } = params;
|
|
16
|
+
const validUntil = Math.floor(Date.now() / 1000) + timeout;
|
|
17
|
+
const jettonWalletAddress = yield getJettonWalletAddress({
|
|
18
|
+
client,
|
|
19
|
+
jettonMasterAddress,
|
|
20
|
+
ownerAddress: walletAddress,
|
|
21
|
+
});
|
|
22
|
+
const jettonWalletAddr = Address.parse(jettonWalletAddress);
|
|
23
|
+
const recipientAddr = Address.parse(recipientAddress);
|
|
24
|
+
const walletAddr = Address.parse(walletAddress);
|
|
25
|
+
const isTestnet = network === CHAIN.TESTNET;
|
|
26
|
+
// Build jetton transfer payload
|
|
27
|
+
// Jetton transfer message format (TEP-74):
|
|
28
|
+
// transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16)
|
|
29
|
+
// destination:MsgAddress response_destination:MsgAddress
|
|
30
|
+
// custom_payload:(Maybe ^Cell) forward_ton_amount:(VarUInteger 16)
|
|
31
|
+
// forward_payload:(Either Cell ^Cell) = InternalMsgBody;
|
|
32
|
+
const forwardPayloadCell = forwardPayload
|
|
33
|
+
? beginCell()
|
|
34
|
+
.storeUint(0, 32) // text comment opcode
|
|
35
|
+
.storeStringTail(forwardPayload)
|
|
36
|
+
.endCell()
|
|
37
|
+
: beginCell().endCell(); // empty cell
|
|
38
|
+
const jettonTransferBody = beginCell()
|
|
39
|
+
.storeUint(0xf8a7ea5, 32) // jetton transfer op code
|
|
40
|
+
.storeUint(0, 64) // query_id (use 0 or timestamp)
|
|
41
|
+
.storeCoins(jettonAmount) // amount of jettons to transfer
|
|
42
|
+
.storeAddress(recipientAddr) // destination address
|
|
43
|
+
.storeAddress(walletAddr) // response_destination (excess TON goes here)
|
|
44
|
+
.storeBit(0) // custom_payload (null)
|
|
45
|
+
.storeCoins(forwardTonAmount) // forward_ton_amount
|
|
46
|
+
.storeBit(0) // forward_payload in this slice (not separate cell)
|
|
47
|
+
.storeSlice(forwardPayloadCell.beginParse()) // forward_payload content
|
|
48
|
+
.endCell();
|
|
49
|
+
// Total TON = forwardTonAmount + gas for the jetton transfer operation
|
|
50
|
+
const totalAmount = forwardTonAmount + gasAmount;
|
|
51
|
+
// Create TON Connect compatible message
|
|
52
|
+
const message = {
|
|
53
|
+
address: jettonWalletAddr.toString({
|
|
54
|
+
bounceable: true,
|
|
55
|
+
testOnly: isTestnet,
|
|
56
|
+
urlSafe: true,
|
|
57
|
+
}),
|
|
58
|
+
amount: totalAmount.toString(),
|
|
59
|
+
payload: jettonTransferBody.toBoc().toString('base64'),
|
|
60
|
+
};
|
|
61
|
+
const request = {
|
|
62
|
+
from: walletAddr.toString({
|
|
63
|
+
bounceable: false,
|
|
64
|
+
testOnly: isTestnet,
|
|
65
|
+
urlSafe: true,
|
|
66
|
+
}),
|
|
67
|
+
messages: [message],
|
|
68
|
+
network,
|
|
69
|
+
validUntil,
|
|
70
|
+
};
|
|
71
|
+
return request;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export { prepareJettonTransfer };
|
|
@@ -0,0 +1,45 @@
|
|
|
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 index = require('../../types/index.cjs');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Prepares a native TON transfer transaction
|
|
12
|
+
*
|
|
13
|
+
* @param params - Transfer parameters
|
|
14
|
+
* @returns TON Connect SendTransactionRequest
|
|
15
|
+
*/
|
|
16
|
+
const prepareTonTransfer = (params) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const { walletAddress, recipient, amount, timeout = 60, network = index.CHAIN.MAINNET, } = params;
|
|
18
|
+
const validUntil = Math.floor(Date.now() / 1000) + timeout;
|
|
19
|
+
const recipientAddress = ton.Address.parse(recipient);
|
|
20
|
+
const amountNano = ton.toNano(amount.toString());
|
|
21
|
+
const walletAddr = ton.Address.parse(walletAddress);
|
|
22
|
+
const isTestnet = network === index.CHAIN.TESTNET;
|
|
23
|
+
// Create TON Connect compatible message
|
|
24
|
+
const message = {
|
|
25
|
+
address: recipientAddress.toString({
|
|
26
|
+
bounceable: false,
|
|
27
|
+
testOnly: isTestnet,
|
|
28
|
+
urlSafe: true,
|
|
29
|
+
}),
|
|
30
|
+
amount: amountNano.toString(),
|
|
31
|
+
};
|
|
32
|
+
const request = {
|
|
33
|
+
from: walletAddr.toString({
|
|
34
|
+
bounceable: false,
|
|
35
|
+
testOnly: isTestnet,
|
|
36
|
+
urlSafe: true,
|
|
37
|
+
}),
|
|
38
|
+
messages: [message],
|
|
39
|
+
network,
|
|
40
|
+
validUntil,
|
|
41
|
+
};
|
|
42
|
+
return request;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
exports.prepareTonTransfer = prepareTonTransfer;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TonClient } from '@ton/ton';
|
|
2
|
+
import { CHAIN, SendTransactionRequest } from '../../types';
|
|
3
|
+
export interface PrepareTonTransferParams {
|
|
4
|
+
/** Sender wallet address */
|
|
5
|
+
walletAddress: string;
|
|
6
|
+
/** Recipient address */
|
|
7
|
+
recipient: string;
|
|
8
|
+
/** Amount in TON (will be converted to nanotons) */
|
|
9
|
+
amount: string | number;
|
|
10
|
+
/** TonClient instance */
|
|
11
|
+
client: TonClient;
|
|
12
|
+
/** Network (MAINNET or TESTNET, default: MAINNET) */
|
|
13
|
+
network?: CHAIN;
|
|
14
|
+
/** Message timeout in seconds (default: 60) */
|
|
15
|
+
timeout?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Prepares a native TON transfer transaction
|
|
19
|
+
*
|
|
20
|
+
* @param params - Transfer parameters
|
|
21
|
+
* @returns TON Connect SendTransactionRequest
|
|
22
|
+
*/
|
|
23
|
+
export declare const prepareTonTransfer: (params: PrepareTonTransferParams) => Promise<SendTransactionRequest>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { Address, toNano } from '@ton/ton';
|
|
4
|
+
import { CHAIN } from '../../types/index.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Prepares a native TON transfer transaction
|
|
8
|
+
*
|
|
9
|
+
* @param params - Transfer parameters
|
|
10
|
+
* @returns TON Connect SendTransactionRequest
|
|
11
|
+
*/
|
|
12
|
+
const prepareTonTransfer = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const { walletAddress, recipient, amount, timeout = 60, network = CHAIN.MAINNET, } = params;
|
|
14
|
+
const validUntil = Math.floor(Date.now() / 1000) + timeout;
|
|
15
|
+
const recipientAddress = Address.parse(recipient);
|
|
16
|
+
const amountNano = toNano(amount.toString());
|
|
17
|
+
const walletAddr = Address.parse(walletAddress);
|
|
18
|
+
const isTestnet = network === CHAIN.TESTNET;
|
|
19
|
+
// Create TON Connect compatible message
|
|
20
|
+
const message = {
|
|
21
|
+
address: recipientAddress.toString({
|
|
22
|
+
bounceable: false,
|
|
23
|
+
testOnly: isTestnet,
|
|
24
|
+
urlSafe: true,
|
|
25
|
+
}),
|
|
26
|
+
amount: amountNano.toString(),
|
|
27
|
+
};
|
|
28
|
+
const request = {
|
|
29
|
+
from: walletAddr.toString({
|
|
30
|
+
bounceable: false,
|
|
31
|
+
testOnly: isTestnet,
|
|
32
|
+
urlSafe: true,
|
|
33
|
+
}),
|
|
34
|
+
messages: [message],
|
|
35
|
+
network,
|
|
36
|
+
validUntil,
|
|
37
|
+
};
|
|
38
|
+
return request;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export { prepareTonTransfer };
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
var index = require('../../types/index.cjs');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Prepares a v5r1 wallet transaction from an array of actions
|
|
12
|
+
*
|
|
13
|
+
* @param params - Parameters for preparing the transaction
|
|
14
|
+
* @returns The hash to sign and transaction data
|
|
15
|
+
*/
|
|
16
|
+
const prepareTransaction = (params) => {
|
|
17
|
+
const { actionsArray, walletAddress, seqno, validUntil, timeout, networkGlobalId = index.CHAIN.MAINNET, } = params;
|
|
18
|
+
const walletAddr = ton.Address.parse(walletAddress);
|
|
19
|
+
// Build actions cell from actions array
|
|
20
|
+
const actionsCell = ton.beginCell().store(core.storeOutList(actionsArray)).endCell();
|
|
21
|
+
const actions = ton.beginCell()
|
|
22
|
+
.storeBit(1) // storeMaybeRef - we have basic actions
|
|
23
|
+
.storeRef(actionsCell) // ref to basic actions
|
|
24
|
+
.storeBit(0) // no extended actions
|
|
25
|
+
.endCell();
|
|
26
|
+
// Calculate walletId following v5r1 spec:
|
|
27
|
+
// walletId = networkGlobalId XOR context
|
|
28
|
+
// context = (1 bit: isClient=1) + (8 bits: workchain) + (8 bits: version=0) + (15 bits: subwallet=0)
|
|
29
|
+
const context = ton.beginCell()
|
|
30
|
+
.storeUint(1, 1) // isClientContext
|
|
31
|
+
.storeInt(walletAddr.workChain, 8) // workchain
|
|
32
|
+
.storeUint(0, 8) // wallet_version (v5r1 = 0)
|
|
33
|
+
.storeUint(0, 15) // subwalletNumber
|
|
34
|
+
.endCell()
|
|
35
|
+
.beginParse()
|
|
36
|
+
.loadInt(32);
|
|
37
|
+
const walletIdValue = BigInt(networkGlobalId) ^ BigInt(context);
|
|
38
|
+
// Build the signing message according to v5r1 spec
|
|
39
|
+
// opcode | walletId | valid_until/timeout | seqno | actions
|
|
40
|
+
const signingMessage = ton.beginCell()
|
|
41
|
+
.storeUint(ton.WalletContractV5R1.OpCodes.auth_signed_external, 32)
|
|
42
|
+
.storeInt(walletIdValue, 32)
|
|
43
|
+
.storeUint(validUntil, 32)
|
|
44
|
+
.storeUint(seqno, 32)
|
|
45
|
+
.storeSlice(actions.beginParse());
|
|
46
|
+
// Calculate hash to sign
|
|
47
|
+
const dataToSign = signingMessage.endCell();
|
|
48
|
+
const hashToSign = dataToSign.hash();
|
|
49
|
+
const hashToSignHex = hashToSign.toString('hex');
|
|
50
|
+
// Store the signing message
|
|
51
|
+
const messageBody = dataToSign.toBoc().toString('base64');
|
|
52
|
+
const transactionData = {
|
|
53
|
+
address: walletAddress,
|
|
54
|
+
messageBody,
|
|
55
|
+
seqno,
|
|
56
|
+
timeout,
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
hashToSign,
|
|
60
|
+
hashToSignHex,
|
|
61
|
+
transactionData,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
exports.prepareTransaction = prepareTransaction;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { OutActionSendMsg } from '@ton/core';
|
|
3
|
+
import { CHAIN, type TonTransactionData } from '../../types';
|
|
4
|
+
export interface PrepareTransactionParams {
|
|
5
|
+
/** Array of actions to include in the transaction */
|
|
6
|
+
actionsArray: OutActionSendMsg[];
|
|
7
|
+
/** Sender wallet address */
|
|
8
|
+
walletAddress: string;
|
|
9
|
+
/** Current wallet seqno */
|
|
10
|
+
seqno: number;
|
|
11
|
+
/** Unix timestamp when transaction expires */
|
|
12
|
+
validUntil: number;
|
|
13
|
+
/** Transaction timeout in seconds (for transactionData) */
|
|
14
|
+
timeout: number;
|
|
15
|
+
/** Network global ID (-239 for mainnet, -3 for testnet) */
|
|
16
|
+
networkGlobalId?: CHAIN;
|
|
17
|
+
}
|
|
18
|
+
export interface PrepareTransactionResult {
|
|
19
|
+
/** Hash to sign as Buffer */
|
|
20
|
+
hashToSign: Buffer;
|
|
21
|
+
/** Hash to sign as hex string */
|
|
22
|
+
hashToSignHex: string;
|
|
23
|
+
/** Transaction data for executeTransaction */
|
|
24
|
+
transactionData: TonTransactionData;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Prepares a v5r1 wallet transaction from an array of actions
|
|
28
|
+
*
|
|
29
|
+
* @param params - Parameters for preparing the transaction
|
|
30
|
+
* @returns The hash to sign and transaction data
|
|
31
|
+
*/
|
|
32
|
+
export declare const prepareTransaction: (params: PrepareTransactionParams) => PrepareTransactionResult;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { Address, beginCell, WalletContractV5R1 } from '@ton/ton';
|
|
3
|
+
import { storeOutList } from '@ton/core';
|
|
4
|
+
import { CHAIN } from '../../types/index.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Prepares a v5r1 wallet transaction from an array of actions
|
|
8
|
+
*
|
|
9
|
+
* @param params - Parameters for preparing the transaction
|
|
10
|
+
* @returns The hash to sign and transaction data
|
|
11
|
+
*/
|
|
12
|
+
const prepareTransaction = (params) => {
|
|
13
|
+
const { actionsArray, walletAddress, seqno, validUntil, timeout, networkGlobalId = CHAIN.MAINNET, } = params;
|
|
14
|
+
const walletAddr = Address.parse(walletAddress);
|
|
15
|
+
// Build actions cell from actions array
|
|
16
|
+
const actionsCell = beginCell().store(storeOutList(actionsArray)).endCell();
|
|
17
|
+
const actions = beginCell()
|
|
18
|
+
.storeBit(1) // storeMaybeRef - we have basic actions
|
|
19
|
+
.storeRef(actionsCell) // ref to basic actions
|
|
20
|
+
.storeBit(0) // no extended actions
|
|
21
|
+
.endCell();
|
|
22
|
+
// Calculate walletId following v5r1 spec:
|
|
23
|
+
// walletId = networkGlobalId XOR context
|
|
24
|
+
// context = (1 bit: isClient=1) + (8 bits: workchain) + (8 bits: version=0) + (15 bits: subwallet=0)
|
|
25
|
+
const context = beginCell()
|
|
26
|
+
.storeUint(1, 1) // isClientContext
|
|
27
|
+
.storeInt(walletAddr.workChain, 8) // workchain
|
|
28
|
+
.storeUint(0, 8) // wallet_version (v5r1 = 0)
|
|
29
|
+
.storeUint(0, 15) // subwalletNumber
|
|
30
|
+
.endCell()
|
|
31
|
+
.beginParse()
|
|
32
|
+
.loadInt(32);
|
|
33
|
+
const walletIdValue = BigInt(networkGlobalId) ^ BigInt(context);
|
|
34
|
+
// Build the signing message according to v5r1 spec
|
|
35
|
+
// opcode | walletId | valid_until/timeout | seqno | actions
|
|
36
|
+
const signingMessage = beginCell()
|
|
37
|
+
.storeUint(WalletContractV5R1.OpCodes.auth_signed_external, 32)
|
|
38
|
+
.storeInt(walletIdValue, 32)
|
|
39
|
+
.storeUint(validUntil, 32)
|
|
40
|
+
.storeUint(seqno, 32)
|
|
41
|
+
.storeSlice(actions.beginParse());
|
|
42
|
+
// Calculate hash to sign
|
|
43
|
+
const dataToSign = signingMessage.endCell();
|
|
44
|
+
const hashToSign = dataToSign.hash();
|
|
45
|
+
const hashToSignHex = hashToSign.toString('hex');
|
|
46
|
+
// Store the signing message
|
|
47
|
+
const messageBody = dataToSign.toBoc().toString('base64');
|
|
48
|
+
const transactionData = {
|
|
49
|
+
address: walletAddress,
|
|
50
|
+
messageBody,
|
|
51
|
+
seqno,
|
|
52
|
+
timeout,
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
hashToSign,
|
|
56
|
+
hashToSignHex,
|
|
57
|
+
transactionData,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { prepareTransaction };
|