title | disqus |
---|---|
ZkSync Dart SDK |
hackmd |
[TOC]
- Connect to the zkSync network.
- Deposit assets from Ethereum into zkSync.
- Make transfers.
- Withdraw funds back to Ethereum mainnet (or testnet).
Using this SDK requires precompiled binary of zkSync cryptography implementation. Please download directly from official repo
Then just add this sdk as a dependency into your app build configuration.
name: <your_app_name>
...
environment:
sdk: '>=2.10.0 <3.0.0'
dependencies:
zksync: ^0.0.1
...
Native library is precompiled for the following platforms:
- Linux x86_64
- OSX x86_64 (MacOS 11 BigSur included)
- Windows x86_64
- Arm64-v8a
- Armeabi-v7a
- x86
- x86_64
- i386
- x86_64
Client library is divided into three separate packages. Just add required into imports
block of your main file;
import 'package:zksync/client.dart'; // ZkSync RPC/REST client
import 'package:zksync/credentials.dart'; // Crypto Credentials
import 'package:zksync/zksync.dart'; // Main Wallet
All messages in zkSync network must be signed by the private key. There are two keys required: Level 1 (L1) for Ethereum and Level 2 (L2) for zkSync network.
To operate in zkSync network you need to create ZkSigner
instance first. There are few ways to create it:
Using seed bytes (like MNEMONIC phrase) with the length >= 32
final zkSigner = ZksSigner.seed(SEED);
Using raw private key
final rawPrivateKey = hex.decode('0x...');
final zkSigner = ZksSigner.raw(rawPrivateKey);
Using raw private key in hex
final zkSigner = ZksSigner.hex('0x...');
Using EthSigner (explained below). The private key used by ZkSigner is implicitly derived by signing a special message with Ethereum L1 key.
final ethSigner = ...;
final zkSigner = await ZksSigher.fromEthSigner(ethSigner, ChainId.Rinkeby);
To interract with Ethereum L1 chain (to make a Deposit
or Withdraw
funds), you'll need EthSigner
instance. It can be instantiated in several different ways:
Using raw private key in hex
final ethSigner = EthSigner.hex(privateKey, chainId: ChainId.Rinkeby.getChainId());
Using raw private key
final rawPrivateKey = hex.decode('0x...');
final ethSigner = EthSigner.raw(privateKey);
Using Credentials
from Web3dart
import 'package:web3dart/web3dart.dart' as web3;
final credentials = web3.EthPrivateKey.fromHex(hexKey);
In order to interact with both zkSync and Ethereum networks you'll need to create providers and provide endpoints to blockchain nodes
This SDK has predefined URLs for the following networks ChainId.Mainnet
, ChainId.Ropsten
, ChainId.Rinkeby
that are officially supported by MatterLabs. Also you can use local node for testing ChainId.Localhost
or simply set endpoint to http://127.0.0.1:3030
final zksync = ZkSyncClient.fromChainId(ChainId.Rinkeby);
You can also create ZkSyncClient
with any custom endpoint URL
import 'package:http/http.dart';
final zksync = ZkSyncClient('http://localhost:3030', Client());
For onchain operations in Ethereum network you can use EthereumClient
final ethSigner = ...;
final ethereum =
EthereumClient('http://localhost:8545', ethSigner.credentials, ChainId.Rinkeby);
To control and operate with your account in zkSync you can use the Wallet
. It can sign transactions with the key stored in ZkSigner
and EthSigner
, then send signed transactions into zkSync network using ZkSyncClient
.
final ethSigner = ...;
final zkSigner = ...;
final ethClient = ...;
final zksClient = ...;
final wallet = Wallet(zksClient, ethClient, zkSigner, ethSigner);
In order to deposit assets from Ethereum network into zkSync please use the following sequence:
final ethSigner = ...;
final ethClient = ...;
final receiver = await ethSigner.extractAddress();
final depositTx = await ethClient.deposit(Token.eth,
EtherAmount.fromUnitAndValue(EtherUnit.ether, 1).getInWei, receiver);
In order to check your account balance in zkSync network please use the following commands:
final wallet = ...;
final state = await wallet.getState();
final balance = state.commited.balances['ETH'];
In order to make any transactions in zkSync network, you'll need to register your ZkSigner's public key first. Please use the following command to do this:
final zkSigner = ...;
final wallet = ...;
final authTx = await wallet.setSigningKey(
ZksPubkeyHash.fromHex(zkSigner.publicKeyHash),
token: Token.eth);
print(authTx);
After funds Deposit
ed and account Unlock
ed, you can transfer funds inside zkSync network.
Please note, that it is possible to send assets within zkSync to any Ethereum address, without preliminary registration in zkSync!
In the example below, we're going to transfer 0.1 ETH
final wallet = ...;
final receiver =
EthereumAddress.fromHex('0x...');
final tx = await wallet.transfer(
receiver, EtherAmount.fromUnitAndValue(EtherUnit.eth, 0.1).getInWei,
token: Token.eth);
print(tx);
All your funds can be withdrawn back to any yours account in Ethereum. Please use the following commands:
final wallet = ...;
final withdrawTx = await wallet.withdraw(
receiver, EtherAmount.fromUnitAndValue(EtherUnit.eth, 0.5).getInWei,
token: Token.eth);
print(withdrawTx);
Assets will be withdrawn to the target address after a zero-knowledge proof of zkSync block with this operation is generated and verified by the mainnet contract (which usually takes about 2-10 min).
Also you can force full withdrawal of all your funds back to your onchain account with a single command:
On zkSync
final wallet = ...;
final exitTx = await wallet.forcedExit(receiver, token: Token.eth);
print(exitTx);
On Ethereum (onchain)
final ethClient = ...;
final wallet = ...;
final exitTx =
await ethClient.fullExit(Token.eth, await wallet.getAccountId());
print(exitTx);