11import { Ton as BaseTon } from '@fireblocks/wallet-derivation' ;
2- import { ConnectedWallet } from '../ConnectedWallet' ;
32import { TonClient , WalletContractV4 } from '@ton/ton' ;
43import { beginCell , Cell , fromNano } from '@ton/core' ;
54import { AccountData } from '../types' ;
65import { defaultTonWalletV4R2code } from './tonParams' ;
76import axios from 'axios' ;
7+ import { LateInitConnectedWallet } from '../LateInitConnectedWallet' ;
8+
9+ export class Ton extends BaseTon implements LateInitConnectedWallet {
10+ public memo : string | undefined ;
11+
12+ public updateDataEndpoint ( memo ?: string ) : void {
13+ this . memo = memo ;
14+ }
15+
16+ public getLateInitLabel ( ) : string {
17+ throw new Error ( 'Method not implemented.' ) ;
18+ }
819
9- export class Ton extends BaseTon implements ConnectedWallet {
1020 public rpcURL : string | undefined ;
21+
1122 public setRPCUrl ( url : string ) : void {
1223 this . rpcURL = url ;
1324 }
14- private client = new TonClient ( {
15- endpoint : this . isTestnet ? 'https://testnet.toncenter.com/api/v2/jsonRPC' : 'https://toncenter.com/api/v2/jsonRPC' ,
16- } ) ;
25+
26+ private client : TonClient | undefined ;
27+
28+ private init ( ) {
29+ this . client = new TonClient ( {
30+ endpoint : this . rpcURL ! ,
31+ } ) ;
32+ }
33+
1734 private tonWallet = WalletContractV4 . create ( { publicKey : Buffer . from ( this . publicKey . replace ( '0x' , '' ) , 'hex' ) , workchain : 0 } ) ;
1835
1936 public async getBalance ( ) : Promise < number > {
20- await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
21- const contract = this . client . open ( this . tonWallet ) ;
22- return Number ( fromNano ( await contract . getBalance ( ) ) ) ;
37+ if ( this . client ) {
38+ await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
39+ const contract = this . client . open ( this . tonWallet ) ;
40+ return Number ( fromNano ( await contract . getBalance ( ) ) ) ;
41+ } else {
42+ this . relayLogger . error ( 'TON: Client failed to initialize' ) ;
43+ throw new Error ( 'TON: Client failed to initialize' ) ;
44+ }
2345 }
46+
2447 public async broadcastTx ( tx : string ) : Promise < string > {
2548 try {
49+ // init the TonClient
50+ this . init ( ) ;
51+
52+ // parse the tx back to Ton Cell
2653 const body = Cell . fromBoc ( Buffer . from ( tx , 'base64' ) ) [ 0 ] ;
2754 const pubKey = Buffer . from ( this . publicKey . replace ( '0x' , '' ) , 'hex' ) ;
28-
2955 const externalMessage = beginCell ( ) . storeUint ( 0b10 , 2 ) . storeUint ( 0 , 2 ) . storeAddress ( this . tonWallet . address ) . storeCoins ( 0 ) ;
30-
3156 const seqno = await this . getSeqno ( ) ;
3257 if ( seqno === 0 ) {
3358 // for the fist transaction we initialize a state init struct which consists of init struct and code
@@ -40,11 +65,16 @@ export class Ton extends BaseTon implements ConnectedWallet {
4065 }
4166 const finalExternalMessage = externalMessage . storeBit ( 1 ) . storeRef ( body ) . endCell ( ) ;
4267
43- await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
44- await this . client . sendFile ( finalExternalMessage . toBoc ( ) ) ;
45- const txHash = finalExternalMessage . hash ( ) . toString ( 'hex' ) ;
46- this . relayLogger . debug ( `TON: Tx broadcasted: ${ txHash } ` ) ;
47- return txHash ;
68+ if ( this . client ) {
69+ // broadcast Tx and calc TxHash
70+ await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
71+ await this . client . sendFile ( finalExternalMessage . toBoc ( ) ) ;
72+ const txHash = finalExternalMessage . hash ( ) . toString ( 'hex' ) ;
73+ this . relayLogger . debug ( `TON: Tx broadcasted: ${ txHash } ` ) ;
74+ return txHash ;
75+ } else {
76+ throw new Error ( 'TON: Client failed to initialize' ) ;
77+ }
4878 } catch ( e ) {
4979 this . relayLogger . error ( `TON: Error broadcasting tx: ${ e } ` ) ;
5080 if ( axios . isAxiosError ( e ) ) {
@@ -53,20 +83,25 @@ export class Ton extends BaseTon implements ConnectedWallet {
5383 throw e ;
5484 }
5585 }
86+
5687 public async prepare ( ) : Promise < AccountData > {
57- // get the balance
58- const balance = await this . getBalance ( ) ; // returned in nanoTon
88+ // init the TonClient
89+ this . init ( ) ;
90+ // get the balance, returned in nanoTon
91+ const balance = await this . getBalance ( ) ;
5992
6093 // fee for regular tx is hardcoded to 0.02 TON
6194 const feeRate = 0.02 ;
62- await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
95+ await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
96+
6397 // get seqno of the wallet, set it as exrtaParams
6498 const seqno = await this . getSeqno ( ) ;
6599 const extraParams = new Map < string , any > ( ) ;
66100 extraParams . set ( 'seqno' , seqno ) ;
67101
68102 const preperedData = {
69103 balance,
104+ memo : this . memo ,
70105 feeRate,
71106 extraParams,
72107 insufficientBalance : balance < 0.005 ,
@@ -76,21 +111,20 @@ export class Ton extends BaseTon implements ConnectedWallet {
76111 }
77112 private async getSeqno ( ) {
78113 await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
79- return await this . client . open ( this . tonWallet ) . getSeqno ( ) ;
114+ return await this . client ! . open ( this . tonWallet ) . getSeqno ( ) ;
80115 }
81116
82117 private createStateInit ( pubKey : Buffer ) {
83118 // the initial data cell our contract will hold. Wallet V4 has an extra value for plugins in the end
84119 const dataCell = beginCell ( )
85120 . storeUint ( 0 , 32 ) // Seqno 0 for the first tx
86- . storeUint ( 698983191 , 32 ) // Subwallet ID
121+ . storeUint ( 698983191 , 32 ) // Subwallet ID -> https://docs.ton.org/v3/guidelines/smart-contracts/howto/wallet#subwallet-ids
87122 . storeBuffer ( pubKey ) // Public Key
88123 . storeBit ( 0 ) // only for Wallet V4
89124 . endCell ( ) ;
90125
91126 // we take a boiler place already made WalletV4R2 code
92127 const codeCell = Cell . fromBoc ( Buffer . from ( defaultTonWalletV4R2code , 'base64' ) ) [ 0 ] ;
93-
94128 const stateInit = beginCell ( )
95129 . storeBit ( 0 ) // No split_depth
96130 . storeBit ( 0 ) // No special
@@ -100,7 +134,6 @@ export class Ton extends BaseTon implements ConnectedWallet {
100134 . storeRef ( dataCell )
101135 . storeBit ( 0 ) // No library
102136 . endCell ( ) ;
103-
104137 return stateInit ;
105138 }
106139}
0 commit comments