Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
[wip]: add L2 chains support #8 #7
Browse files Browse the repository at this point in the history
  • Loading branch information
naftalimurgor committed Jun 16, 2024
1 parent 6ac61e6 commit b17a549
Showing 1 changed file with 72 additions and 29 deletions.
101 changes: 72 additions & 29 deletions src/bridge/WBGL.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
import Web3 from 'web3'
import { ethers, Wallet } from 'ethers'
import fetch from 'node-fetch'
import abi from '../abi/WBGL.json'
import { IBridgeConfig } from '../types'
import { ChaindIds } from '../chains'
import { IContracts } from '.'
import WBGL_ABI from '../abi/WBGL'
import { ChaindIds } from '../chains'
import { IBridgeConfig } from '../types'
import { WBGL_CONTRACT_ADDRESS_BNB, WBGL_CONTRACT_ADDRESS_ETH } from './constants'

/**
* @param bglAddress is the address to receive BGL to
* @param wbglAmount is the amount of WBGL tokens to swap for BGL amount
* @param sourceWBGLAddress is the address/account containing WBGL tokens to swap.
* NOTE: should be address linked to the signer(wallet) to be able to sign messages authorizing the swap.
*/
export interface WBGLBGLExchangePair {
bglAddress: string
to: string
recepientWbglAddress: string
sourceWBGLAddress?: string
wbglAmount: number
}

export class WBGL {
/**
* @member web3 instance to use.
*/
private readonly web3: Web3
private readonly provider: ethers.providers.JsonRpcProvider | ethers.providers.Web3Provider
/**
* @member chainId The chainId of the network to use
*/
private readonly chainId: number | string | ChaindIds
private readonly chainName: string
private readonly bridgeEndpoint = 'https://bglswap.com/app/'
private readonly evmPrivateKey: string

constructor(config: IBridgeConfig) {
this.web3 = new Web3(config.provider)
this.provider = config.provider
this.chainId = config.chainId
this.chainName = config.chainName
this.evmPrivateKey = config.evmPrivateKey
}

/// START PUBLIC METHODS
Expand All @@ -40,15 +45,15 @@ export class WBGL {
* @param from
* swapWBGLforBGL swaps WBGL for BGL to recepient Bitgesell address
*/
public async swapWBGLforBGL({
public async swapWBGLtoBGL({
bglAddress,
recepientWbglAddress,
wbglAmount
wbglAmount,
sourceWBGLAddress
}: WBGLBGLExchangePair) {
try {
const addressess = await this.web3.eth.getAccounts()
const account = recepientWbglAddress || addressess[0]
const signature = await this._signMessage(account, bglAddress)
const signer = await this._getSigner()
const account = sourceWBGLAddress || await signer.getAddress()
const signature = await this._signMessage(bglAddress)

const headers = {
'Content-Type': 'application/json',
Expand All @@ -61,11 +66,13 @@ export class WBGL {
ethAddress: account,
signature,
}

const res = await fetch(`${this.bridgeEndpoint}submit/wbgl`, {
headers,
body: JSON.stringify(dataObject),
method: 'POST'
})

const bridgeResponse = await res.json()

const { address: sendAddress } = bridgeResponse
Expand All @@ -78,38 +85,74 @@ export class WBGL {
} /// END OF PUBLIC METHODS

/// START PRIVATE METHODS
private async _signMessage(account: string, message: string) {
return await this.web3.eth.sign(message, account)
private async _signMessage(message: string) {
const signer = await this._getSigner()
const signedMessage = await signer.signMessage(message)
return signedMessage
}

public async _sendWbgl(


private async _sendWbgl(
from: string,
to: string,
amount: number
) {
const value = this.web3.utils.toWei(amount, 'ether')
const tokenAddress = await this._getWBGLTokenAddress()
// TODO: perform gas estimate to avoid exhorbitant gas fees
const WBGContractInstance = new this.web3.eth.Contract(abi, tokenAddress)
const tx = await WBGContractInstance.methods.transfer(to, value).send({ from })
return tx
}

private async _getWBGLTokenAddress(): Promise<string> {
try {
const res = await fetch(`${this.bridgeEndpoint}/contracts`)
const contracts = await res.json() as IContracts
return contracts[this.isChainBsc(this.chainId) ? 'bsc' : 'eth']
const txData = {
to,
gasLimit: null,
nonce: null,
maxFeePerGas: null,
value: null, //
maxPriorityFeePerGas: null
}

const value = ethers.utils.parseUnits(String(amount), 18)
const tokenAddress = this._getWBGLTokenAddress()
const signer = await this._getSigner()
const nonce = await signer.getTransactionCount()
const feeData = await signer.getFeeData()
const price = feeData.maxFeePerGas

// TODO: perform gas estimate to avoid exhorbitant gas fees
const WBGLContractInstance = new ethers.Contract(tokenAddress, WBGL_ABI)
const estimate = WBGLContractInstance.transfer.estimateGas(to, value)
const result = await estimate()

txData.value = value
txData.gasLimit = result
txData.nonce = nonce
txData.maxFeePerGas = price
txData.maxPriorityFeePerGas = price.div(10)

// const fee = price.mul(txData.gasLimit)

const tx = await WBGLContractInstance.methods.transfer(to, value).send({ from })
const request = await WBGLContractInstance.transfer(txData.to, txData.value, tx)
return request

} catch (error) {
return error
}
}

private _getWBGLTokenAddress(): string {
// @TODO: add Optimism and Arbitrum contract addresses
return this.isChainBsc(this.chainId) ? WBGL_CONTRACT_ADDRESS_BNB : WBGL_CONTRACT_ADDRESS_ETH
}


// @TODO: include Arbitrum, Optimism checks
private isChainBsc(chainId: string | number): boolean {
const bscChainIds: (string | number)[] = ['0x38', '0x61'] // Binance Smart Chain (Mainnet & Testnet) chain IDs
return bscChainIds.includes(chainId)
} /// END OF PRIVATE METHODS
}

private async _getSigner() {
if (this.evmPrivateKey) return new Wallet(this.evmPrivateKey, this.provider)
else return this.provider.getSigner() // Web3Provider injected by MetaMask web wallets
} /// END OF PRIVATE METHODS

}

0 comments on commit b17a549

Please sign in to comment.