MerklyClient.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { Contract, ethers } from 'ethers'
  2. import { ChainId, chainInfoMap } from '../config/chain'
  3. import { newLogger } from '../utils/logger'
  4. export class MerklyClient {
  5. wallet: ethers.Wallet
  6. chainId: number
  7. provider: ethers.JsonRpcProvider
  8. router: ethers.Contract
  9. static logger = newLogger('MerklyClient')
  10. constructor(privateKey: string, chainId: number) {
  11. const from = chainInfoMap[chainId].merklyInfo
  12. if (!from) {
  13. throw new Error('Unsupported chain')
  14. }
  15. this.chainId = chainId
  16. this.provider = new ethers.JsonRpcProvider(chainInfoMap[chainId].rpcUrl)
  17. this.wallet = new ethers.Wallet(privateKey, this.provider)
  18. this.router = new Contract(
  19. chainInfoMap[chainId].merklyInfo.routerAddress,
  20. [
  21. 'function quoteBridge(uint32 _destination, uint amount) external view returns (uint fee)',
  22. 'function bridgeETH(uint32 _destination, uint amount) public payable returns (bytes32 messageId)',
  23. 'function bridgeWETH(uint32 _destination, uint amount) public payable returns (bytes32 messageId)',
  24. ],
  25. this.wallet,
  26. )
  27. }
  28. async bridge(toChainId: number = ChainId.ARBITRUM) {
  29. const toInfo = chainInfoMap[toChainId].merklyInfo
  30. if (!toInfo) {
  31. throw new Error('Unsupported chain')
  32. }
  33. const balance = await this.provider.getBalance(this.wallet.address)
  34. const quote = await this.router.quoteBridge(toInfo.merklyChainId, balance)
  35. if (balance > quote) {
  36. const feeData = await this.provider.getFeeData()
  37. const estimatedGas = await this.router.bridgeETH.estimateGas(toInfo.merklyChainId, balance - quote, {
  38. value: balance,
  39. })
  40. const gasCost = (feeData.gasPrice * estimatedGas * 108n) / 100n
  41. if (balance < quote + gasCost) {
  42. MerklyClient.logger.error('Insufficient balance')
  43. // throw new Error('Insufficient balance')
  44. }
  45. const tx = await this.router.bridgeETH(toInfo.merklyChainId, balance - quote - gasCost, {
  46. value: balance - gasCost,
  47. gasLimit: (estimatedGas * 105n) / 100n,
  48. gasPrice: feeData.gasPrice,
  49. })
  50. return tx.hash
  51. } else {
  52. MerklyClient.logger.error('Insufficient balance')
  53. }
  54. }
  55. }