· 4 months ago · May 13, 2025, 01:50 PM
1import { Environment } from './test';
2import { join } from 'path';
3import { validate_transaction_ton_wallet } from '../src/dtos';
4import TonWeb from 'tonweb';
5const TonWebS = require('tonweb');
6import 'reflect-metadata';
7import { mnemonicToPrivateKey } from '@ton/crypto';
8import { toNano } from '@ton/core';
9const config: Environment = (() => {
10 const config = require('dotenv').config({
11 override: true,
12 path: ['.env'].map(value => join(__dirname, `../${value}`)),
13 });
14 return {
15 ...validate_transaction_ton_wallet(config.parsed)
16 };
17})();
18const wait = (millis) => {
19 return new Promise(resolve => {
20 setTimeout(resolve, millis);
21 });
22}
23
24export class AccountSubscription {
25 private onTransaction: any;
26 constructor(
27 protected tonweb:TonWeb,
28 protected accountAddress:string,
29 protected startTime:number,
30 onTransaction) {
31 this.onTransaction = onTransaction;
32 }
33
34 async start() {
35 const getTransactions = async (time, offsetTransactionLT, offsetTransactionHash, retryCount) => {
36 const COUNT = 10;
37
38 if (offsetTransactionLT) {
39 console.log(`Get ${COUNT} transactions before transaction ${offsetTransactionLT}:${offsetTransactionHash}`);
40 } else {
41 console.log(`Get last ${COUNT} transactions`);
42 }
43
44 // TON transaction has composite ID: account address (on which the transaction took place) + transaction LT (logical time) + transaction hash.
45 // So TxID = address+LT+hash, these three parameters uniquely identify the transaction.
46 // In our case, we are monitoring one wallet and the address is `accountAddress`.
47
48 let transactions;
49
50 try {
51 transactions = await this.tonweb.provider.getTransactions(this.accountAddress, COUNT, offsetTransactionLT, offsetTransactionHash);
52 } catch (e) {
53 console.error(e);
54 // if an API error occurs, try again
55 retryCount++;
56 if (retryCount < 10) {
57 await wait(retryCount * 1000);
58 return getTransactions(time, offsetTransactionLT, offsetTransactionHash, retryCount);
59 } else {
60 return 0;
61 }
62 }
63
64 console.log(`Got ${transactions.length} transactions`);
65
66 if (!transactions.length) {
67 // If you use your own API instance make sure the code contains this fix https://github.com/toncenter/ton-http-api/commit/a40a31c62388f122b7b7f3da7c5a6f706f3d2405
68 // If you use public toncenter.com then everything is OK.
69 return time;
70 }
71
72 if (!time) time = transactions[0].utime;
73
74 for (const tx of transactions) {
75
76 if (tx.utime < this.startTime) {
77 return time;
78 }
79
80 await this.onTransaction(tx);
81 }
82
83 if (transactions.length === 1) {
84 return time;
85 }
86
87 const lastTx = transactions[transactions.length - 1];
88 return await getTransactions(time, lastTx.transaction_id.lt, lastTx.transaction_id.hash, 0);
89 }
90
91
92 let isProcessing = false;
93
94 const tick = async () => {
95 if (isProcessing) return;
96 isProcessing = true;
97
98 try {
99 const result = await getTransactions(undefined, undefined, undefined, 0);
100 if (result > 0) {
101 this.startTime = result; // store in your database
102 }
103 } catch (e) {
104 console.error(e);
105 }
106
107 isProcessing = false;
108 }
109
110 setInterval(tick, 10 * 1000); // poll every 10 seconds
111 tick();
112 }
113}
114const tonweb:TonWeb = new TonWebS(new TonWebS.HttpProvider(config.TRANSACTION_TON_ENDPOINT))
115
116async function a(){
117
118 const onTransaction = async (tx) => {
119 console.log(tx)
120 if (tx.in_msg.source && tx.out_msgs.length === 0) {
121
122 if (tx.in_msg.msg_data && tx.in_msg.msg_data['@type'] !== 'msg.dataText') { // no text comment
123 return;
124 }
125
126 const value = tx.in_msg.value; // amount in nano-Toncoins (1 Toncoin = 1e9 nano-Toncoins)
127 const senderAddress = tx.in_msg.source; // sender address
128 const payload = tx.in_msg.message; // transfer text comment (in our case, the user should send the UUID as a text comment)
129
130 // here you find the payment in your database by UUID,
131 // check that the payment has not been processed yet and the amount matches,
132 // save to the database that this payment has been processed.
133
134 console.log(`Receive ${TonWeb.utils.fromNano(value)} TON from ${senderAddress} with comment "${payload}"`);
135 }
136 }
137
138 const accountSubscription = new AccountSubscription(tonweb, config.TRANSACTION_TON_WALLET_ADDRESS, 0, onTransaction);
139 await accountSubscription.start();
140}
141// a()
142async function sleep(time:number = 60750){
143 return new Promise(resolve => setTimeout(resolve,time))
144}
145async function c(){
146 let keyPair = await mnemonicToPrivateKey(config.TRANSACTION_TON_WALLET_MNEMONIC.split(' '));
147 // const Wl = tonweb.wallet.all['v4R2']
148 // @ts-ignore
149 // const wallet = new Wl(tonweb,{publicKey:keyPair.publicKey});
150 const wallet = tonweb.wallet.create({address: config.TRANSACTION_TON_WALLET_ADDRESS});
151 const address = await wallet.getAddress();
152 const nonBounceableAddress = address.toString(true, true, false);
153 const seqno = await wallet.methods.seqno().call() || 0;
154 console.log({address,nonBounceableAddress,seqno})
155 const deploy = wallet.deploy(keyPair.secretKey)
156 console.log({deploy})
157 await sleep()
158 const deployFee = await deploy.estimateFee() // get estimate fee of deploy
159 await sleep()
160 const deploySended = await deploy.send() // deploy wallet contract to blockchain
161 await sleep()
162 const deployQuery = await deploy.getQuery(); // get deploy query Cell
163 console.log({
164 deployFee,
165 deploySended,
166 deployQuery
167 })
168 const transfer = wallet.methods.transfer({
169 secretKey: keyPair.secretKey,
170 toAddress: 'UQBWAXieOu25vZiWQ6Qbc2MqNp3FO3HLADuEF5Mt7N9Q6Tfa',
171 amount: tonweb.utils.toNano(0.01), // 0.01 TON
172 seqno: seqno,
173 payload: 'Hello',
174 sendMode: 3,
175 })
176 console.log({ transfer})
177 await sleep()
178 const transferFee = await transfer.estimateFee(); // get estimate fee of transfer
179 await sleep()
180 const transferSended = await transfer.send(); // send transfer query to blockchain
181 await sleep()
182 const transferQuery = await transfer.getQuery(); // get transfer query Cell
183 console.log({transferFee,transferSended,transferQuery})
184 await sleep()
185 const history = await tonweb.getTransactions(address);
186 await sleep()
187 const balance = await tonweb.getBalance(address);
188 console.log({ history,balance })
189
190}
191(async ()=>{
192
193 try{
194 await c()
195 }catch (e) {
196 throw e;
197 }
198})()
199