Skip to content

Latest commit

 

History

History
240 lines (203 loc) · 10.5 KB

15.md

File metadata and controls

240 lines (203 loc) · 10.5 KB
title actions requireLogin material
Putting everything together
checkAnswer
hints
true
editor
language startingCode answer
JavaScript
src/alice.js src/bob.js src/utils.js
(async () => { const ethers = require('ethers') const zksync = require('zksync') const utils = require('./utils') const token = 'ETH' const amountToDeposit = '0.05' const amountToTransfer = '0.02' const amountToWithdraw = '0.002' const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME) const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME) console.log('Creating a new Rinkeby wallet for Alice') const aliceRinkebyWallet = new ethers.Wallet(process.env.ALICE_PRIVATE_KEY, ethersProvider) // Account #78 console.log(`Alice's Rinkeby address is: ${aliceRinkebyWallet.address}`) const aliceInitialRinkebyBalance = await aliceRinkebyWallet.getBalance() console.log(`Alice's initial balance on Rinkeby is: ${ethers.utils.formatEther(aliceInitialRinkebyBalance)}`) console.log('Creating a zkSync wallet for Alice') const aliceZkSyncWallet = await utils.initAccount(aliceRinkebyWallet, zkSyncProvider, zksync) console.log('Depositing') await utils.depositToZkSync(aliceZkSyncWallet, token, amountToDeposit, ethers) await utils.displayZkSyncBalance(aliceZkSyncWallet, ethers) await utils.registerAccount(aliceZkSyncWallet) console.log('Transferring') const transferFee = await utils.getFee('Transfer', aliceRinkebyWallet.address, token, zkSyncProvider, ethers) await utils.transfer(aliceZkSyncWallet, process.env.BOB_ADDRESS, amountToTransfer, transferFee, token, zksync, ethers) console.log('Withdrawing') // Start here })()
(async () => { const ethers = require('ethers') const zksync = require('zksync') const utils = require('./utils') const SLEEP_INTERVAL = process.env.SLEEP_INTERVAL || 5000 const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME) const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME) const bobRinkebyWallet = new ethers.Wallet(process.env.BOB_PRIVATE_KEY, ethersProvider) console.log(`Bob's Rinkeby address is: ${bobRinkebyWallet.address}`) console.log(`Bob's initial balance on Rinkeby is: ${ethers.utils.formatEther(await bobRinkebyWallet.getBalance())}`) const bobZkSyncWallet = await utils.initAccount(bobRinkebyWallet, zkSyncProvider, zksync) process.on('SIGINT', () => { console.log('Disconnecting') // Disconnect process.exit() }) setInterval(async () => { await utils.displayZkSyncBalance(bobZkSyncWallet, ethers) console.log('---') }, SLEEP_INTERVAL) })()
async function getZkSyncProvider (zksync, networkName) { let zkSyncProvider try { zkSyncProvider = await zksync.getDefaultProvider(networkName) } catch (error) { console.log('Unable to connect to zkSync.') console.log(error) } return zkSyncProvider } async function getEthereumProvider (ethers, networkName) { let ethersProvider try { // eslint-disable-next-line new-cap ethersProvider = new ethers.getDefaultProvider(networkName) } catch (error) { console.log('Could not connect to Rinkeby') console.log(error) } return ethersProvider } async function initAccount (rinkebyWallet, zkSyncProvider, zksync) { const zkSyncWallet = await zksync.Wallet.fromEthSigner(rinkebyWallet, zkSyncProvider) return zkSyncWallet } async function registerAccount (wallet) { console.log(`Registering the ${wallet.address()} account on zkSync`) if (!await wallet.isSigningKeySet()) { if (await wallet.getAccountId() === undefined) { throw new Error('Unknown account') } const changePubkey = await wallet.setSigningKey() await changePubkey.awaitReceipt() } console.log(`Account ${wallet.address()} registered`) } async function depositToZkSync (zkSyncWallet, token, amountToDeposit, ethers) { const deposit = await zkSyncWallet.depositToSyncFromEthereum({ depositTo: zkSyncWallet.address(), token: token, amount: ethers.utils.parseEther(amountToDeposit) }) try { await deposit.awaitReceipt() } catch (error) { console.log('Error while awaiting confirmation from the zkSync operators.') console.log(error) } } async function transfer (from, toAddress, amountToTransfer, transferFee, token, zksync, ethers) { const closestPackableAmount = zksync.utils.closestPackableTransactionAmount( ethers.utils.parseEther(amountToTransfer)) const closestPackableFee = zksync.utils.closestPackableTransactionFee( ethers.utils.parseEther(transferFee)) const transfer = await from.syncTransfer({ to: toAddress, token: token, amount: closestPackableAmount, fee: closestPackableFee }) const transferReceipt = await transfer.awaitReceipt() console.log('Got transfer receipt.') console.log(transferReceipt) } async function getFee(transactionType, address, token, zkSyncProvider, ethers) { const feeInWei = await zkSyncProvider.getTransactionFee(transactionType, address, token) return ethers.utils.formatEther(feeInWei.totalFee.toString()) } async function withdrawToEthereum (wallet, amountToWithdraw, withdrawalFee, token, zksync, ethers) { const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(ethers.utils.parseEther(amountToWithdraw)) const closestPackableFee = zksync.utils.closestPackableTransactionFee(ethers.utils.parseEther(withdrawalFee)) const withdraw = await wallet.withdrawFromSyncToEthereum({ ethAddress: wallet.address(), token: token, amount: closestPackableAmount, fee: closestPackableFee }) await withdraw.awaitVerifyReceipt() console.log('ZKP verification is complete') } async function displayZkSyncBalance (wallet, ethers) { const state = await wallet.getAccountState() if (state.committed.balances.ETH) { console.log(`Commited ETH balance for ${wallet.address()}: ${ethers.utils.formatEther(state.committed.balances.ETH)}`) } else { console.log(`Commited ETH balance for ${wallet.address()}: 0`) } if (state.verified.balances.ETH) { console.log(`Verified ETH balance for ${wallet.address()}: ${ethers.utils.formatEther(state.verified.balances.ETH)}`) } else { console.log(`Verified ETH balance for ${wallet.address()}: 0`) } } module.exports = { getZkSyncProvider, getEthereumProvider, depositToZkSync, registerAccount, displayZkSyncBalance, transfer, withdrawToEthereum, getFee, initAccount }
(async () => { const ethers = require('ethers') const zksync = require('zksync') const utils = require('./utils') const token = 'ETH' const amountToDeposit = '0.05' const amountToTransfer = '0.02' const amountToWithdraw = '0.002' const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME) const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME) console.log('Creating a new Rinkeby wallet for Alice') const aliceRinkebyWallet = new ethers.Wallet(process.env.ALICE_PRIVATE_KEY, ethersProvider) // Account #78 console.log(`Alice's Rinkeby address is: ${aliceRinkebyWallet.address}`) const aliceInitialRinkebyBalance = await aliceRinkebyWallet.getBalance() console.log(`Alice's initial balance on Rinkeby is: ${ethers.utils.formatEther(aliceInitialRinkebyBalance)}`) console.log('Creating a zkSync wallet for Alice') const aliceZkSyncWallet = await utils.initAccount(aliceRinkebyWallet, zkSyncProvider, zksync) console.log('Depositing') await utils.depositToZkSync(aliceZkSyncWallet, token, amountToDeposit, ethers) await utils.displayZkSyncBalance(aliceZkSyncWallet, ethers) await utils.registerAccount(aliceZkSyncWallet) console.log('Transferring') const transferFee = await utils.getFee('Transfer', aliceRinkebyWallet.address, token, zkSyncProvider, ethers) await utils.transfer(aliceZkSyncWallet, process.env.BOB_ADDRESS, amountToTransfer, transferFee, token, zksync, ethers) console.log('Withdrawing') const withdrawalFee = await utils.getFee('Withdraw', aliceRinkebyWallet.address, token, zkSyncProvider, ethers) await utils.withdrawToEthereum(aliceZkSyncWallet, amountToWithdraw, withdrawalFee, token, zksync, ethers) })()

Awesome, we're close to being done here!

Now let's say Alice wants to withdraw her tokens to Ethereum. This is a two-step process:

  1. Retrieve the withdrawal transfer fee
  2. Withdraw assets from zkSync to Ethereum

If you didn't use the "Show me the answer" button to finish the previous lesson, the steps in this lesson should be a walk in the park.

Put it to the test

  1. Declare a const variable named withdrawalFee, and use it to store the value returned by a call to the utils.getFee function. The arguments for the utils.getFee call should be mostly the same as the previous time it was called to figure out the fee for a 'Transfer', just replace the first argument with 'Withdraw'.

  2. Call the async function utils.withdrawToEthereum. It takes the following parameters: aliceZkSyncWallet, amountToWithdraw, withdrawalFee, token, zksync, ethers.

Give it a try!

That's it! Now you're ready to run your new apps. We trust you'll be able to do it.