|
|
@@ -1,7 +1,6 @@
|
|
|
import { Inject, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'
|
|
|
import { ethers } from 'ethers'
|
|
|
import { Wallet, Provider, utils } from 'zksync-web3'
|
|
|
-import web3Config from './web3.config'
|
|
|
import { ConfigType } from '@nestjs/config'
|
|
|
import { AccountsService } from '../accounts/accounts.service'
|
|
|
import erc20 from './erc20.json'
|
|
|
@@ -39,18 +38,45 @@ import mintSquareAbi from './mintSquareAbi.json'
|
|
|
|
|
|
@Injectable()
|
|
|
export class Web3Service {
|
|
|
+ config: { [key: string]: Web3Config } = {
|
|
|
+ testnet: {
|
|
|
+ ethereumNetwork: 'goerli',
|
|
|
+ ethereumExplorer: 'https://goerli.etherscan.io',
|
|
|
+ infuraApiKey: '6e36ce031e304b79af723a0a28789083',
|
|
|
+ zksyncRpcUrl: 'https://testnet.era.zksync.dev',
|
|
|
+ zksyncChainId: 280,
|
|
|
+ zksyncExplorer: 'https://goerli.explorer.zksync.io',
|
|
|
+ liquidityManagerAddress: '0x25727b360604E1e6B440c3B25aF368F54fc580B6',
|
|
|
+ tokenAddress: '0x0faF6df7054946141266420b43783387A78d82A9',
|
|
|
+ quoterAddress: '0xE93D1d35a63f7C6b51ef46a27434375761a7Db28',
|
|
|
+ swapAddress: '0x3040EE148D09e5B92956a64CDC78b49f48C0cDdc',
|
|
|
+ mintAddress: '0x74E6d686F70fD5829f00dB0F95EC0f153970baD3'
|
|
|
+ },
|
|
|
+ mainnet: {
|
|
|
+ ethereumNetwork: 'goerli',
|
|
|
+ ethereumExplorer: 'https://goerli.etherscan.io',
|
|
|
+ infuraApiKey: '6e36ce031e304b79af723a0a28789083',
|
|
|
+ zksyncRpcUrl: 'https://testnet.era.zksync.dev',
|
|
|
+ zksyncChainId: 280,
|
|
|
+ zksyncExplorer: 'https://goerli.explorer.zksync.io',
|
|
|
+ liquidityManagerAddress: '0x25727b360604E1e6B440c3B25aF368F54fc580B6',
|
|
|
+ tokenAddress: '0x0faF6df7054946141266420b43783387A78d82A9',
|
|
|
+ quoterAddress: '0xE93D1d35a63f7C6b51ef46a27434375761a7Db28',
|
|
|
+ swapAddress: '0x3040EE148D09e5B92956a64CDC78b49f48C0cDdc',
|
|
|
+ mintAddress: '0x74E6d686F70fD5829f00dB0F95EC0f153970baD3'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
constructor(
|
|
|
- @Inject(web3Config.KEY)
|
|
|
- private readonly web3Configuration: ConfigType<typeof web3Config>,
|
|
|
private readonly accountService: AccountsService
|
|
|
) {}
|
|
|
|
|
|
- async zkDeposit(accountId, amount) {
|
|
|
+ async zkDeposit(accountId, amount, network: NetworkType) {
|
|
|
const account = await this.accountService.findById(accountId)
|
|
|
- const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
|
|
|
+ const provider = new Provider(this.config[network].zksyncRpcUrl)
|
|
|
const ethProvider = new ethers.providers.InfuraProvider(
|
|
|
- this.web3Configuration.ethereumNetwork,
|
|
|
- this.web3Configuration.infuraApiKey
|
|
|
+ this.config[network].ethereumNetwork,
|
|
|
+ this.config[network].infuraApiKey
|
|
|
)
|
|
|
const wallet = new Wallet(account.privateKey, provider, ethProvider)
|
|
|
const deposit = await wallet.deposit({
|
|
|
@@ -76,19 +102,19 @@ export class Web3Service {
|
|
|
// Logger.log('finalizedEthBalance', ethers.utils.formatEther(finalizedEthBalance))
|
|
|
}
|
|
|
|
|
|
- async zkWidthdraw(accountId, amount) {
|
|
|
+ async zkWidthdraw(accountId, amount, network: NetworkType) {
|
|
|
const account = await this.accountService.findById(accountId)
|
|
|
- const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
|
|
|
+ const provider = new Provider(this.config[network].zksyncRpcUrl)
|
|
|
const ethProvider = new ethers.providers.InfuraProvider(
|
|
|
- this.web3Configuration.ethereumNetwork,
|
|
|
- this.web3Configuration.infuraApiKey
|
|
|
+ this.config[network].ethereumNetwork,
|
|
|
+ this.config[network].infuraApiKey
|
|
|
)
|
|
|
const wallet = new Wallet(account.privateKey, provider, ethProvider)
|
|
|
const withdrawL2 = await wallet.withdraw({
|
|
|
token: utils.ETH_ADDRESS,
|
|
|
amount: ethers.utils.parseEther(amount)
|
|
|
})
|
|
|
- Logger.log(`Widthdraw sent. ${this.web3Configuration.zksyncExplorer}/tx/${withdrawL2.hash}`)
|
|
|
+ Logger.log(`Widthdraw sent. ${this.config[network].zksyncExplorer}/tx/${withdrawL2.hash}`)
|
|
|
// // Await processing of the deposit on L1
|
|
|
// const ethereumTxReceipt = await deposit.waitL1Commit()
|
|
|
|
|
|
@@ -107,27 +133,27 @@ export class Web3Service {
|
|
|
// Logger.log('finalizedEthBalance', ethers.utils.formatEther(finalizedEthBalance))
|
|
|
}
|
|
|
|
|
|
- async addLiquidity(accountId, amount) {
|
|
|
- const chainId = this.web3Configuration.ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
+ async addLiquidity(accountId, amount, network: NetworkType) {
|
|
|
+ const chainId = this.config[network].ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
const account = await this.accountService.findById(accountId)
|
|
|
- const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
|
|
|
+ const provider = new Provider(this.config[network].zksyncRpcUrl)
|
|
|
const zkWallet = new Wallet(account.privateKey).connect(provider)
|
|
|
const chain = initialChainTable[chainId]
|
|
|
- const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
|
|
|
+ const web3 = new Web3(new Web3.providers.HttpProvider(this.config[network].zksyncRpcUrl))
|
|
|
console.log('address: ', zkWallet.address)
|
|
|
|
|
|
const liquidityManagerContract = getLiquidityManagerContract(
|
|
|
- this.web3Configuration.liquidityManagerAddress,
|
|
|
+ this.config[network].liquidityManagerAddress,
|
|
|
web3 as any
|
|
|
)
|
|
|
- console.log('liquidity manager address: ', this.web3Configuration.liquidityManagerAddress)
|
|
|
+ console.log('liquidity manager address: ', this.config[network].liquidityManagerAddress)
|
|
|
|
|
|
const tokenA = getGasToken(chainId)
|
|
|
console.log('tokenA: ', tokenA)
|
|
|
- const tokenB = await fetchToken(this.web3Configuration.tokenAddress, chain, web3 as any)
|
|
|
+ const tokenB = await fetchToken(this.config[network].tokenAddress, chain, web3 as any)
|
|
|
console.log('tokenB: ', tokenB)
|
|
|
|
|
|
- await this.approve(tokenB.address, this.web3Configuration.liquidityManagerAddress, zkWallet)
|
|
|
+ await this.approve(tokenB.address, this.config[network].liquidityManagerAddress, zkWallet, network)
|
|
|
|
|
|
const fee = 2000 // 2000 means 0.2%
|
|
|
const poolAddress = await getPoolAddress(liquidityManagerContract, tokenA, tokenB, fee)
|
|
|
@@ -192,29 +218,29 @@ export class Web3Service {
|
|
|
const tx = await zkWallet.sendTransaction({
|
|
|
from: options.from,
|
|
|
value: Web3.utils.numberToHex(options.value),
|
|
|
- to: this.web3Configuration.liquidityManagerAddress,
|
|
|
+ to: this.config[network].liquidityManagerAddress,
|
|
|
data: calling.encodeABI(),
|
|
|
gasLimit
|
|
|
})
|
|
|
console.log('tx: ', tx)
|
|
|
}
|
|
|
|
|
|
- async removeLiquidity(accountId) {
|
|
|
- const chainId = this.web3Configuration.ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
+ async removeLiquidity(accountId, network: NetworkType) {
|
|
|
+ const chainId = this.config[network].ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
const account = await this.accountService.findById(accountId)
|
|
|
- const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
|
|
|
+ const provider = new Provider(this.config[network].zksyncRpcUrl)
|
|
|
const wallet = new Wallet(account.privateKey).connect(provider)
|
|
|
const chain = initialChainTable[chainId]
|
|
|
- const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
|
|
|
+ const web3 = new Web3(new Web3.providers.HttpProvider(this.config[network].zksyncRpcUrl))
|
|
|
|
|
|
const liquidityManagerContract = getLiquidityManagerContract(
|
|
|
- this.web3Configuration.liquidityManagerAddress,
|
|
|
+ this.config[network].liquidityManagerAddress,
|
|
|
web3 as any
|
|
|
)
|
|
|
- Logger.log('liquidity manager address: ', this.web3Configuration.liquidityManagerAddress)
|
|
|
+ Logger.log('liquidity manager address: ', this.config[network].liquidityManagerAddress)
|
|
|
|
|
|
const tokenA = getGasToken(chainId)
|
|
|
- const tokenB = await fetchToken(this.web3Configuration.tokenAddress, chain, web3 as any)
|
|
|
+ const tokenB = await fetchToken(this.config[network].tokenAddress, chain, web3 as any)
|
|
|
|
|
|
Logger.log(`tokenA: ${tokenA.symbol} tokenB: ${tokenB.symbol}`, 'FetchLiquidities')
|
|
|
const liquidities = await fetchLiquiditiesOfAccount(
|
|
|
@@ -259,15 +285,15 @@ export class Web3Service {
|
|
|
console.log('gas limit: ', gasLimit)
|
|
|
const tx0 = await wallet.sendTransaction({
|
|
|
from: wallet.address,
|
|
|
- to: this.web3Configuration.liquidityManagerAddress,
|
|
|
+ to: this.config[network].liquidityManagerAddress,
|
|
|
data: decLiquidityCalling.encodeABI(),
|
|
|
gasLimit
|
|
|
})
|
|
|
console.log('decLiquidityCalling tx: ', JSON.stringify(tx0, null, 4))
|
|
|
}
|
|
|
|
|
|
- async allowance(tokenAddress, spender, wallet: Wallet): Promise<number> {
|
|
|
- const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
|
|
|
+ async allowance(tokenAddress, spender, wallet: Wallet, network: NetworkType): Promise<number> {
|
|
|
+ const web3 = new Web3(new Web3.providers.HttpProvider(this.config[network].zksyncRpcUrl))
|
|
|
const tokenAContract = new web3.eth.Contract(erc20, tokenAddress)
|
|
|
// @ts-ignore
|
|
|
const allowanceCalling = tokenAContract.methods.allowance(wallet.address, spender)
|
|
|
@@ -276,12 +302,12 @@ export class Web3Service {
|
|
|
return out as unknown as number
|
|
|
}
|
|
|
|
|
|
- async approve(tokenAddress, spender, wallet: Wallet) {
|
|
|
- const allowance = await this.allowance(tokenAddress, spender, wallet)
|
|
|
+ async approve(tokenAddress, spender, wallet: Wallet, network: NetworkType) {
|
|
|
+ const allowance = await this.allowance(tokenAddress, spender, wallet, network)
|
|
|
if (allowance > 0) {
|
|
|
return
|
|
|
}
|
|
|
- const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
|
|
|
+ const web3 = new Web3(new Web3.providers.HttpProvider(this.config[network].zksyncRpcUrl))
|
|
|
const tokenAContract = new web3.eth.Contract(erc20, tokenAddress)
|
|
|
// @ts-ignore
|
|
|
const approveCalling = tokenAContract.methods.approve(spender, '0xffffffffffffffffffffffffffffffff')
|
|
|
@@ -297,13 +323,13 @@ export class Web3Service {
|
|
|
console.log('approve tx: ', JSON.stringify(tx0, null, 4))
|
|
|
}
|
|
|
|
|
|
- async swapWithExactOutput(accountId, amount) {
|
|
|
+ async swapWithExactOutput(accountId, amount, network: NetworkType) {
|
|
|
const account = await this.accountService.findById(accountId)
|
|
|
- const chainId = this.web3Configuration.ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
+ const chainId = this.config[network].ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
const chain = initialChainTable[chainId]
|
|
|
- const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
|
|
|
+ const provider = new Provider(this.config[network].zksyncRpcUrl)
|
|
|
const wallet = new Wallet(account.privateKey).connect(provider)
|
|
|
- const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
|
|
|
+ const web3 = new Web3(new Web3.providers.HttpProvider(this.config[network].zksyncRpcUrl))
|
|
|
console.log('address: ', wallet.address)
|
|
|
|
|
|
const balance = await web3.eth.getBalance(wallet.address)
|
|
|
@@ -311,7 +337,7 @@ export class Web3Service {
|
|
|
|
|
|
const fromToken = getGasToken(chainId)
|
|
|
console.log('fromToken: ', fromToken)
|
|
|
- const toToken = await fetchToken(this.web3Configuration.tokenAddress, chain, web3 as any)
|
|
|
+ const toToken = await fetchToken(this.config[network].tokenAddress, chain, web3 as any)
|
|
|
console.log('toToken: ', toToken)
|
|
|
const fee = 2000 // 2000 means 0.2%
|
|
|
|
|
|
@@ -320,7 +346,7 @@ export class Web3Service {
|
|
|
const toTokenBalance = await toTokenContract.methods.balanceOf(wallet.address).call()
|
|
|
console.log(toToken.symbol + ' balance: ' + amount2Decimal(new BigNumber(toTokenBalance), toToken))
|
|
|
|
|
|
- const quoterContract = getQuoterContract(this.web3Configuration.quoterAddress, web3 as any)
|
|
|
+ const quoterContract = getQuoterContract(this.config[network].quoterAddress, web3 as any)
|
|
|
|
|
|
const receiveAmount = new BigNumber(amount).times(10 ** toToken.decimal)
|
|
|
|
|
|
@@ -339,7 +365,7 @@ export class Web3Service {
|
|
|
console.log(toToken.symbol + ' to desired: ', amount)
|
|
|
console.log(fromToken.symbol + ' to pay: ', payAmountDecimal)
|
|
|
|
|
|
- const swapContract = getSwapContract(this.web3Configuration.swapAddress, web3 as any)
|
|
|
+ const swapContract = getSwapContract(this.config[network].swapAddress, web3 as any)
|
|
|
|
|
|
const swapParams = {
|
|
|
...params,
|
|
|
@@ -363,29 +389,29 @@ export class Web3Service {
|
|
|
const tx = await wallet.sendTransaction({
|
|
|
value: Web3.utils.numberToHex(options.value),
|
|
|
data: swapCalling.arguments[0][0],
|
|
|
- to: this.web3Configuration.swapAddress,
|
|
|
+ to: this.config[network].swapAddress,
|
|
|
gasLimit
|
|
|
})
|
|
|
console.log(tx)
|
|
|
}
|
|
|
|
|
|
- async mint(accountId) {
|
|
|
+ async mint(accountId, network: NetworkType) {
|
|
|
const account = await this.accountService.findById(accountId)
|
|
|
- const chainId = this.web3Configuration.ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
+ const chainId = this.config[network].ethereumNetwork == 'goerli' ? ChainId.ZkSyncAlphaTest : ChainId.ZkSyncEra
|
|
|
const chain = initialChainTable[chainId]
|
|
|
- const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
|
|
|
+ const provider = new Provider(this.config[network].zksyncRpcUrl)
|
|
|
const wallet = new Wallet(account.privateKey).connect(provider)
|
|
|
- const web3 = new Web3(new Web3.providers.HttpProvider(this.web3Configuration.zksyncRpcUrl))
|
|
|
+ const web3 = new Web3(new Web3.providers.HttpProvider(this.config[network].zksyncRpcUrl))
|
|
|
console.log('address: ', wallet.address)
|
|
|
|
|
|
- const contract = new web3.eth.Contract(mintSquareAbi, this.web3Configuration.mintAddress, web3 as any)
|
|
|
+ const contract = new web3.eth.Contract(mintSquareAbi, this.config[network].mintAddress, web3 as any)
|
|
|
// @ts-ignore
|
|
|
const mintCall = await contract.methods.mint('ipfs://QmPxcRPvjMDrv7d4WjQK5KNXkuXudGhKjPTDnzuFkRQ6Fs')
|
|
|
const gasLimit = await mintCall.estimateGas({ from: wallet.address })
|
|
|
console.log('gas limit: ', gasLimit)
|
|
|
const tx = await wallet.sendTransaction({
|
|
|
from: wallet.address,
|
|
|
- to: this.web3Configuration.mintAddress,
|
|
|
+ to: this.config[network].mintAddress,
|
|
|
data: mintCall.encodeABI(),
|
|
|
gasLimit
|
|
|
})
|