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