xiongzhu преди 2 години
родител
ревизия
fd813374ae
променени са 7 файла, в които са добавени 110 реда и са изтрити 103 реда
  1. 0 12
      .env
  2. 0 7
      .env.production
  3. 15 0
      src/web3/types.ts
  4. 0 21
      src/web3/web3.config.ts
  5. 20 12
      src/web3/web3.controller.ts
  6. 1 3
      src/web3/web3.module.ts
  7. 74 48
      src/web3/web3.service.ts

+ 0 - 12
.env

@@ -65,15 +65,3 @@ WX_MCH_CERT_PATH=src/cert/
 WX_NOTIFY_URL=https://gpt.izouma.com/api/notify/weixin
 
 REDIS_URI=redis://:3a4FSzu8ErP9$CQ&@147.139.168.134:6379/0
-
-ETHEREUM_NETWORK=goerli
-ETHEREUM_EXPLORER=https://goerli.etherscan.io
-INFURA_API_KEY=6e36ce031e304b79af723a0a28789083
-ZKSYNC_RPC_URL=https://testnet.era.zksync.dev
-ZKSYNC_CHAIN_ID=280
-ZKSYNC_EXPLORER=https://goerli.explorer.zksync.io
-LIQUIDITY_MANAGER_ADDRESS=0x25727b360604E1e6B440c3B25aF368F54fc580B6
-TOKEN_ADDRESS=0x0faF6df7054946141266420b43783387A78d82A9
-QUOTER_ADDRESS=0xE93D1d35a63f7C6b51ef46a27434375761a7Db28
-SWAP_ADDRESS=0x3040EE148D09e5B92956a64CDC78b49f48C0cDdc
-MINT_ADDRESS=0x74E6d686F70fD5829f00dB0F95EC0f153970baD3

+ 0 - 7
.env.production

@@ -65,10 +65,3 @@ WX_MCH_CERT_PATH=src/cert/
 WX_NOTIFY_URL=https://gpt.izouma.com/api/notify/weixin
 
 REDIS_URI=redis://:3a4FSzu8ErP9$CQ&@127.0.0.1:6379/0
-
-ETHEREUM_NETWORK=mainnet
-ETHEREUM_EXPLORER=https://etherscan.io
-INFURA_API_KEY=6e36ce031e304b79af723a0a28789083
-ZKSYNC_RPC_URL=https://mainnet.era.zksync.io
-ZKSYNC_CHAIN_ID=324
-ZKSYNC_EXPLORER=https://explorer.zksync.io

+ 15 - 0
src/web3/types.ts

@@ -0,0 +1,15 @@
+declare type NetworkType = 'test' | 'prod'
+
+declare interface Web3Config {
+    ethereumNetwork: string
+    ethereumExplorer: string
+    infuraApiKey: string
+    zksyncRpcUrl: string
+    zksyncChainId: number
+    zksyncExplorer: string
+    liquidityManagerAddress: string
+    tokenAddress: string
+    quoterAddress: string
+    swapAddress: string
+    mintAddress: string
+}

+ 0 - 21
src/web3/web3.config.ts

@@ -1,21 +0,0 @@
-import { ConfigService, registerAs } from '@nestjs/config'
-import { config } from 'dotenv'
-
-config()
-
-const configService = new ConfigService()
-
-export default registerAs('web3', () => {
-    return {
-        ethereumNetwork: configService.get<string>('ETHEREUM_NETWORK'),
-        ethereumExplorer: configService.get<string>('ETHEREUM_EXPLORER'),
-        infuraApiKey: configService.get<string>('INFURA_API_KEY'),
-        zksyncRpcUrl: configService.get<string>('ZKSYNC_RPC_URL'),
-        zksyncExplorer: configService.get<string>('ZKSYNC_EXPLORER'),
-        liquidityManagerAddress: configService.get<string>('LIQUIDITY_MANAGER_ADDRESS'),
-        tokenAddress: configService.get<string>('TOKEN_ADDRESS'),
-        quoterAddress: configService.get<string>('QUOTER_ADDRESS'),
-        swapAddress: configService.get<string>('SWAP_ADDRESS'),
-        mintAddress: configService.get<string>('MINT_ADDRESS'),
-    }
-})

+ 20 - 12
src/web3/web3.controller.ts

@@ -6,32 +6,40 @@ export class Web3Controller {
     constructor(private readonly web3Service: Web3Service) {}
 
     @Post('/zk-deposit')
-    public async zkDeposit(@Body() { accountId, amount }) {
-        return await this.web3Service.zkDeposit(accountId, amount)
+    public async zkDeposit(
+        @Body() { accountId, amount, network }: { accountId: string; amount: string; network: NetworkType }
+    ) {
+        return await this.web3Service.zkDeposit(accountId, amount, network)
     }
 
     @Post('/zk-withdraw')
-    public async zkWidthdraw(@Body() { accountId, amount }) {
-        return await this.web3Service.zkWidthdraw(accountId, amount)
+    public async zkWidthdraw(
+        @Body() { accountId, amount, network }: { accountId: string; amount: string; network: NetworkType }
+    ) {
+        return await this.web3Service.zkWidthdraw(accountId, amount, network)
     }
 
     @Post('/add-liquidity')
-    public async addLiquidity(@Body() { accountId, amount }) {
-        return await this.web3Service.addLiquidity(accountId, amount)
+    public async addLiquidity(
+        @Body() { accountId, amount, network }: { accountId: string; amount: string; network: NetworkType }
+    ) {
+        return await this.web3Service.addLiquidity(accountId, amount, network)
     }
 
     @Post('/remove-liquidity')
-    public async removeLiquidity(@Body() { accountId }) {
-        return await this.web3Service.removeLiquidity(accountId)
+    public async removeLiquidity(@Body() { accountId, network }: { accountId: string; network: NetworkType }) {
+        return await this.web3Service.removeLiquidity(accountId, network)
     }
 
     @Post('/swap-exact-out')
-    public async swap(@Body() { accountId, amount }) {
-        return await this.web3Service.swapWithExactOutput(accountId, amount)
+    public async swap(
+        @Body() { accountId, amount, network }: { accountId: string; amount: string; network: NetworkType }
+    ) {
+        return await this.web3Service.swapWithExactOutput(accountId, amount, network)
     }
 
     @Post('/mint')
-    public async mint(@Body() { accountId }) {
-        return await this.web3Service.mint(accountId)
+    public async mint(@Body() { accountId, network }: { accountId: string; network: NetworkType }) {
+        return await this.web3Service.mint(accountId, network)
     }
 }

+ 1 - 3
src/web3/web3.module.ts

@@ -1,12 +1,10 @@
 import { Module } from '@nestjs/common'
 import { Web3Service } from './web3.service'
 import { Web3Controller } from './web3.controller'
-import { ConfigModule } from '@nestjs/config'
-import web3Config from './web3.config'
 import { AccountsModule } from '../accounts/accounts.module'
 
 @Module({
-    imports: [ConfigModule.forFeature(web3Config), AccountsModule],
+    imports: [AccountsModule],
     providers: [Web3Service],
     controllers: [Web3Controller]
 })

+ 74 - 48
src/web3/web3.service.ts

@@ -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
         })