Make Transaction
In the following article, we will use this wallet as example:
1
Address: 0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF
2
Private Key: 0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf
Copied!

Layer-1

The only transaction that made on Layer-1 is deposit. It has two sub-types which are DepositETH and DepositERC20.

ABIs

1
[
2
{
3
"constant": false,
4
"inputs": [
5
{
6
"internalType": "contract IERC20",
7
"name": "_token",
8
"type": "address"
9
},
10
{
11
"internalType": "uint104",
12
"name": "_amount",
13
"type": "uint104"
14
},
15
{
16
"internalType": "address",
17
"name": "_franklinAddr",
18
"type": "address"
19
}
20
],
21
"name": "depositERC20",
22
"outputs": [],
23
"payable": false,
24
"stateMutability": "nonpayable",
25
"type": "function"
26
},
27
{
28
"constant": false,
29
"inputs": [
30
{
31
"internalType": "address",
32
"name": "_franklinAddr",
33
"type": "address"
34
}
35
],
36
"name": "depositETH",
37
"outputs": [],
38
"payable": true,
39
"stateMutability": "payable",
40
"type": "function"
41
}
42
]
Copied!

Deposit ETH

Example Code:
1
import { Wallet, Contract, utils } from 'ethers'
2
3
const contract = new Contract('0x8ECa806Aecc86CE90Da803b080Ca4E3A9b8097ad', ABI, wallet)
4
const wallet = new Wallet('0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf')
5
6
async function depositETH(amount) {
7
const tx = await contract.depositETH(wallet.address, {
8
value: utils.parse(amount)
9
})
10
return tx
11
}
12
13
// deposit 1 ETH
14
depositETH('1').then(console.log)
Copied!

Deposit ERC20

Like other projects, you must approve ZKSwap's main contract address to spend your ERC20 tokens in order to deposit. Be careful for those tokens that has limit on changing allowance (See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729).
Example code:
1
import { Wallet, Contract, utils } from 'ethers'
2
3
const contract = new Contract('0x8ECa806Aecc86CE90Da803b080Ca4E3A9b8097ad', ABI, wallet)
4
const wallet = new Wallet('0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf')
5
6
async function depositERC20(amount, tokenAddress) {
7
const tokenContract = new Contract(tokenAddress, ERC20_ABI, wallet)
8
// check allowance
9
const allowance = await tokenContract.allowance(wallet.address, MAIN_CONTRACT_ADDRESS)
10
let nonce
11
if (allowance.lt(utils.parse(amount)) {
12
// approve
13
const MAX_AMOUNT = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
14
const approveTx = await tokenContract.allow(MAIN_CONTRACT_ADDRESS, MAX_AMOUNT)
15
nonce = approveTx.nonce + 1
16
}
17
const tx = await contract.depositERC20(tokenAddress, utils.parse(amount), wallet.address, {
18
nonce
19
})
20
return tx
21
}
22
23
// deposit 100 ZKS
24
depositERC20('100', '0xe4815ae53b124e7263f08dcdbbb757d41ed658c6').then(console.log)
Copied!

Layer-2

When submitting transaction to ZKSwap, the API requires 3 fields: tx, signature and fastProcessing.In the following docs, Signed Transaction refers to the tx field and ETH Signature refers to the signature field.

Private Key

Sign the following message with Layer-1's private key to get Layer-2's seed. And use zkSync's crypto libraries to get private key.
Plain Text
JavaScript
1
Access ZKSwap account.
2
3
Only sign this message for a trusted client!
Copied!
1
const msg = 'Access ZKSwap account.\n\nOnly sign this message for a trusted client!'
Copied!
Here's a full example of getting private key using zksync-crypto in JavaScript.
1
import { Wallet, Contract, utils } from 'ethers'
2
import { privateKeyFromSeed, private_key_to_pubkey_hash } from 'zksync-crypto'
3
4
const wallet = new Wallet('0x1c1a49fea9a4ede1dc8e582639f498d41fa3c4a9e2ab2b9d740a4a3ec14e1cbf')
5
6
async function getPrivateKey() {
7
const msg = 'Access ZKSwap account.\n\nOnly sign this message for a trusted client!'
8
const signature = await wallet.signMessage(msg)
9
const seed = utils.arrayify(signature)
10
11
// Get private key
12
const privateKey = privateKeyFromSeed(seed)
13
14
return privateKey
15
}
16
17
getPrivateKey().then(console.log)
Copied!

Public Key Hash

After getting private key, you will need to register you publick key hash to ZKSwap so that it can verify transations that you sent.
1
import { utils } from 'ethers'
2
import { private_key_to_pubkey_hash } from 'zksync-crypto'
3
4
const pubKeyHash = `sync:${utils.hexlify(private_key_to_pubkey_hash(privateKey)).substr(2)}`
Copied!

Signature

Before submit transaction to ZKSwap, you need to sign the the transaction data.
1
import { utils } from 'ethers'
2
import { sign_musig } from 'zksync-crypto'
3
4
function signMessage(privateKey, msgBytes) {
5
const signaturePacked = sign_musig(privateKey, msgBytes)
6
7
const pubKey = utils.hexlify(signaturePacked.slice(0, 32)).substr(2)
8
const signature = utils.hexlify(signaturePacked.slice(32)).substr(2)
9
10
return {
11
pubKey,
12
signature
13
}
14
}
15
16
const msgBytes = utils.concat([type, accountId, ...etc])
17
const signature = signMessage(privateKey, msgBytes)
18
Copied!

Change Public Key

After the account has been "registered" on ZKSwap (via transfer or deposit), you can change the account's pubKeyHash in order to make any transaction on Layer-2. This is a special transaction that you don't need to sign it with Layer-2's private key.
Transaction Fields
Field
Type
Comment
type
string
ChangePubKey
accountId
number
Your account ID.
account
address
Your address.
newPkHash
number
The public key hash.
nonce
number
Your current nonce.
ethSignature
string
Layer-1 signature
Signed Transaction Example
1
{
2
"type": "ChangePubKey",
3
"accountId": 83670,
4
"account": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
5
"newPkHash": "sync:83f62ba777515089eb905a375f77f59ddfada116",
6
"nonce": 0,
7
"ethSignature": "0x66c1ef3611a634e400301375b291a0835b0e31237273e1bdab45acc3ef27c761674fd5e5a706566e5175e8e18306f5b8d1d36016f3894e84d527c3c97e92bcf71c"
8
}
Copied!
ETH Signature
Message Template
Message to sign
Signature
1
Register ZKSwap pubkey:
2
3
{pubKeyHash}
4
nonce: {hexlifiedNonce}
5
account id: {hexlifiedAccountId}
6
7
Only sign this message for a trusted client!
Copied!
1
Register ZKSwap pubkey:
2
3
83f62ba777515089eb905a375f77f59ddfada116
4
nonce: 0x00000000
5
account id: 0x000146d6
6
7
Only sign this message for a trusted client!
Copied!
1
0x66c1ef3611a634e400301375b291a0835b0e31237273e1bdab45acc3ef27c761674fd5e5a706566e5175e8e18306f5b8d1d36016f3894e84d527c3c97e92bcf71c
Copied!

Transfer

Transaction Fields
Bytes Order
Field
Type
Bytes Length
Comment
Bytes Example
0
type
string
1
Transfer
0x05
1
accountId
number
4
Your account ID.
0x0000053a
2
from
address
20
Your address.
0x026a25efbcefb2e481d005e4f00ccced0af511ff
3
to
address
20
The target address you want to transfer.
0x961b513dfd3e363c238e0f98219ee02552a847bd
4
token
number
2
The ID of the token.
0x000a
5
amount
string
5
The packed amount you want to transfer.
0x4a817c8008
6
feeToken
number
1
The ID of fee token.
0x0a
7
fee
string
2
0x0000
8
chainId
number
1
11 for mainnet, 128 for ropsten.
0x0b
9
nonce
number
4
Your current nonce.
0x00000001
-
signature
object
Contains your pubKey and signature.
Full Bytes Example
1
0x050000053a026a25efbcefb2e481d005e4f00ccced0af511ff961b513dfd3e363c238e0f98219ee02552a847bd000a4a817c80080a00000b00000001
Copied!
Signed Transaction Example
1
{
2
"type": "Transfer",
3
"accountId": 1338,
4
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
5
"to": "0x961b513dfd3e363c238e0f98219ee02552a847bd",
6
"token": 10,
7
"amount": "1000000000000000000",
8
"feeToken": 10,
9
"fee": "0",
10
"chainId": 11,
11
"nonce": 1,
12
"signature": {
13
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
14
"signature": "7db4f4ce33abf89cbccaff96ae0651c79043dcf965893de71e7388163ec57883b2d4ef9bf264346ceff69f9ba8dfe8624d1fad9a452acf10a5d15f956a0a7b03"
15
}
16
}
Copied!
ETH Signature
Message Template
Message Example
Signature
1
Transfer {readableAmount} {tokenSymbol}
2
To: {to}
3
ChainId {chainId}
4
Nonce: {nonce}
5
Fee: {readableFee} {feeTokenSymbol}
6
Account Id: {accountId}
Copied!
1
Transfer 1.0 ZKS
2
To: 0x961b513dfd3e363c238e0f98219ee02552a847bd
3
Chain Id: 11
4
Nonce: 1
5
Fee: 0.0 ZKS
6
Account Id: 1338
Copied!
1
{
2
"type": "EthereumSignature",
3
"signature": "0xbf8fa93e7da866aa3acb07a6a826e5e61195eba04e3c72a4f02b8fc8221da1f764363817968576013ca515ffe5e1104b5890937150883f3304d0738777af915b1c"
4
}
Copied!

Withdraw

Transaction Fields
Bytes Order
Field
Type
Bytes Length
Comment
Bytes Example
0
type
string
1
Withdraw
0x03
1
accountId
number
4
Your account ID.
0x0000053a
2
from
address
20
Your address.
0x026a25efbcefb2e481d005e4f00ccced0af511ff
3
to
address
20
The target address you want to withdraw to.
0x026a25efbcefb2e481d005e4f00ccced0af511ff
4
token
number
2
The ID of the token you want to withdraw.
0x000a
5
amount
string
16
The amount you want to withdraw.
0x00000000000000000de0b6b3a7640000
6
feeToken
number
1
The ID of fee token.
0x0a
7
fee
string
2
0x4bf0
8
chainId
number
1
11 for mainnet, 128 for ropsten.
0x0b
9
nonce
number
4
Your current nonce.
0x00000002
-
signature
object
Contains your pubKey and signature.
Full Bytes Example
1
0x030000053a026a25efbcefb2e481d005e4f00ccced0af511ff026a25efbcefb2e481d005e4f00ccced0af511ff000a00000000000000000de0b6b3a76400000a4bf00b00000002
Copied!
Signed Transaction Example
1
{
2
"type": "Withdraw",
3
"accountId": 1338,
4
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
5
"to": "0x026a25efbcefb2e481d005e4f00ccced0af511ff",
6
"token": 10,
7
"amount": "1000000000000000000",
8
"feeToken": 10,
9
"fee": "6070000000000000000",
10
"chainId": 11,
11
"nonce": 2,
12
"signature": {
13
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
14
"signature": "68bb8413edc0182812aa90481ff46f0514df9d5d6b5703338f1a292682caad9b04cac623f95b9d26fa31d4a9330ba35b5746fd697853a0512f92b00692fe6d00"
15
}
16
}
Copied!
ETH Signature
Message Template
Message Example
Signature
1
Withdraw {readableAmount} {tokenSymbol}
2
To: {to}
3
ChainId {chainId}
4
Nonce: {nonce}
5
Fee: {readableFee} {feeTokenSymbol}
6
Account Id: {accountId}
Copied!
1
Withdraw 3.4226556417 ZKS
2
To: 0x026a25efbcefb2e481d005e4f00ccced0af511ff
3
ChainId 10
4
Nonce: 2
5
Fee: 1.577 ZKS
6
Account Id: 83670
Copied!
1
{
2
"type": "EthereumSignature",
3
"signature": "0x0440667d6a694b76e5f3a51fa3981a3db95bfc7d3feeb301f403ea6f3bef01d32c9e06920f7b13edd92a6cb22f49d6709fb4f9d41efc09b0a094173b6bbb4f121b"
4
}
Copied!

Swap

Fee

Let's take swap token A for token B as example. There are two cases:
  1. 1.
    If A is a fee token, the fee token of swap is A. The number of fee is calculated by amountIn * 5 / 9995
  2. 2.
    If A is not a fee token, the fee token of swap is B. The number of fee is amountOut * 5 /10000. It's not amountOutMin. amountOut equals amountOutMin then slipplage is 0.
Transaction Fields
Bytes Order
Field
Type
Bytes Length
Comment
Bytes Example
0
type
string
1
Swap
0x0b
1
accountId
number
4
Your account ID.
0x0000053a
2
from
address
20
Your address.
0x026a25efbcefb2e481d005e4f00ccced0af511ff
3
to
address
20
The pair's address.
0xaa45c964e21eafb38574e9d000adbaf85acfbb80
4
tokenIn
number
2
The ID of the token you want to swap in.
0x000a
5
amountIn
string
5
The amount you want to swap in.
0x94efe63009
6
tokenOut
number
2
The ID of the token you want to swap out.
0x0000
7
amountOutMin
string
5
The minimum amount you want to swap out.
0x25004d47c6
8
feeToken
number
1
The ID of fee token.
0x0a
9
fee
string
2
0x7d0d
10
chainId
number
1
11 for mainnet, 128 for ropsten.
0x0b
11
nonce
number
4
Your current nonce.
0x00000003
-
signature
object
Contains your pubKey and signature.
Full Bytes Example
1
0x0b0000053a026a25efbcefb2e481d005e4f00ccced0af511ffaa45c964e21eafb38574e9d000adbaf85acfbb80000a94efe63009000025004d47c60a7d0d0b00000003
Copied!
Signed Transaction Example
1
{
2
"type": "Swap",
3
"accountId": 1338,
4
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
5
"to": "0xaa45c964e21eafb38574e9d000adbaf85acfbb80",
6
"tokenIn": 10,
7
"tokenOut": 0,
8
"amountIn": "19990000000000000000",
9
"amountOutMin": "4966214206000000",
10
"feeToken": 10,
11
"fee": "10000000000000000",
12
"chainId": 11,
13
"nonce": 3,
14
"signature": {
15
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
16
"signature": "3c6c2059ab0e929ed18d6ad4fbbf1cddce0e84b0cb9537069456b16cd01f33a2bc5391f8f7e1b9ae8fdff4c5d05856709e6bfd0e9200f5293386cf1aa6b39c00"
17
}
18
}
Copied!
ETH Signature
Message Template
Message Example
Signature
1
Swap {readableAmontIn} {tokenInSymbol}
2
Minimum: {readableAmontOutMin} {tokenOutSymbol}
3
To: {pairAddress}
4
ChainId {chainId}
5
Nonce: {nonce}
6
Fee: {readableFee} {feeTokenSymbol}
7
Account Id: {accountId}
Copied!
1
Swap 19.99 ZKS
2
Minimum: 0.004966214206 ETH
3
To: 0xaa45c964e21eafb38574e9d000adbaf85acfbb80
4
Chain Id: 11
5
Nonce: 3
6
Fee: 0.01 ZKS
7
Account Id: 1338
Copied!
1
{
2
"type": "EthereumSignature",
3
"signature": "0x66ca505f09e2dbd2aaaa809cac3ec7085ea7831ec58c695566190588a2ced45c0d7e1c235840dd3f547d54ad87e6740bb3d299a89d36460b9eb1e56b25456ef41b"
4
}
Copied!

Add Liquidity

Transaction Fields
Bytes Order
Field
Type
Bytes Length
Comment
Bytes Example
0
type
string
1
AddLiquidity
0x09
1
accountId
number
4
Your account ID.
0x0000053a
2
from
address
20
Your address.
0x026a25efbcefb2e481d005e4f00ccced0af511ff
3
to
address
20
The pair's address.
0xaa45c964e21eafb38574e9d000adbaf85acfbb80
4
tokenA
number
2
The ID of token A.
0x0000
5
amountADesired
number
5
The amount of token A you want to add to the pair.
0xc2cf6f3245
6
amountAMin
string
5
The minimum amount of Token A you want to add to the pair.
0xb911dcd625
7
tokenB
number
2
The ID of the token B.
0x000a
8
amountBDesired
string
5
The amount of token B you want to add to the pair.
0x4a817c8009
9
amountBMin
string
5
The minimum amount of Token B you want to add to the pair.
0x46c7cfe009
10
tokenLiquidity
number
2
The pair ID.
0x4002
11
feeToken
number
1
The ID of fee token.
0x0a
12
fee
string
2
0x0000
13
chainId
number
1
11 for mainnet, 128 for ropsten.
0x0b
14
nonce
number
4
Your current nonce.
0x00000004
-
signature
object
Contains your pubKey and signature.
Full Bytes Example
1
0x090000053a026a25efbcefb2e481d005e4f00ccced0af511ffaa45c964e21eafb38574e9d000adbaf85acfbb800000c2cf6f3245b911dcd625000a4a817c800946c7cfe00940020a00000b00000004
Copied!
Signed Transaction Example
1
{
2
"type": "AddLiquidity",
3
"accountId": 1338,
4
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
5
"to": "0xaa45c964e21eafb38574e9d000adbaf85acfbb80",
6
"tokenA": 0,
7
"tokenB": 10,
8
"tokenLiquidity": 16386,
9
"amountADesired": "2614699457800000",
10
"amountBDesired": "10000000000000000000",
11
"amountAMin": "2483964484900000",
12
"amountBMin": "9500000000000000000",
13
"feeToken": 10,
14
"fee": "0",
15
"chainId": 11,
16
"nonce": 4,
17
"signature": {
18
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
19
"signature": "3506a865b8a0871b706a620abbf7978760f76670c2d563f059d217890349988dd7a37d1cea3f67d5ca691453dd45d282141acac3f4dafb9f7a44b1dda3e0ca00"
20
}
21
}
Copied!
ETH Signature
Message Template
Message Example
Signature
1
AddLiquidity {pairSymbol}
2
Desired: {readableAmontA} {tokenASymbol} {readableAmontB} {tokenBSymbol}
3
Minimum: {readableAmontAMin} {tokenASymbol} {readableAmontBMin} {tokenBSymbol}
4
To: {pairAddress}
5
ChainId {chainId}
6
Nonce: {nonce}
7
Fee: {readableFee} {feeTokenSymbol}
8
Account Id: {accountId}
Copied!
1
AddLiquidity liquidity_0_10
2
Desired: 0.0026146994578 ETH 10.0 ZKS
3
Minimum: 0.0024839644849 ETH 9.5 ZKS
4
To: 0xaa45c964e21eafb38574e9d000adbaf85acfbb80
5
Chain Id: 11
6
Nonce: 4
7
Fee: 0.0 ZKS
8
Account Id: 1338
Copied!
1
{
2
"type": "EthereumSignature",
3
"signature": "0x20c1c26e8f678220189f0a4a444e1686e969faa536a17abc1a30a113d6e4bfc12aa88a2075693857ea410f439d28467b01666bcb01d1b6bb7b8ce3641bd6daea1b"
4
}
Copied!

Remove Liquidity

Transaction Fields
Bytes Order
Field
Type
Comment
Bytes Examplle
0
type
string
1
RemoveLiquidity
0x0a
1
accountId
number
4
Your account ID.
0x0000053a
2
from
address
20
Your address.
0x026a25efbcefb2e481d005e4f00ccced0af511ff
3
to
address
20
The pair's address.
0xaa45c964e21eafb38574e9d000adbaf85acfbb80
4
tokenA
number
2
The ID of token A.
0x0000
5
amountAMin
string
5
The minimum amount of Token A you want to remove from the pair.
0xb96855c485
6
tokenB
number
2
The ID of the token B.
0x000a
7
amountBMin
string
5
The minimum amount of Token B you want to remove from the pair.
0x46a6e21049
8
feeToken
number
1
The ID of fee token.
0x0a
9
fee
string
2
0x0000
10
tokenLiquidity
number
2
The pair ID.
0x4002
11
amountLiquidity
string
5
The amount of LP token you want to remove.
0x77e80cdba7
12
chainId
number
2
11 for mainnet, 128 for ropsten.
0x0b
13
nonce
number
4
Your current nonce.
-
signature
object
Contains your pubKey and signature.
Full Bytes Example
1
0x0a0000053a026a25efbcefb2e481d005e4f00ccced0af511ffaa45c964e21eafb38574e9d000adbaf85acfbb800000b96855c485000a46a6e210490a0000400277e80cdba70b00000005
Copied!
Signed Transaction Example
1
{
2
"type": "RemoveLiquidity",
3
"accountId": 1338,
4
"from": "0x026A25EfbcEFb2e481d005E4F00Ccced0AF511FF",
5
"to": "0xaa45c964e21eafb38574e9d000adbaf85acfbb80",
6
"tokenA": 0,
7
"tokenB": 10,
8
"amountAMin": "2488498128400000",
9
"amountBMin": "9482735746000000000",
10
"tokenLiquidity": 16386,
11
"amountLiquidity": "160935707810000000",
12
"feeToken": 10,
13
"fee": "0",
14
"chainId": 11,
15
"nonce": 5,
16
"signature": {
17
"pubKey": "110ffd569daaee30068fc3c85922d1237f63a41d4749d464b883131e92369204",
18
"signature": "bf0e5c3639e9f9f837e2d141fa9481da8e11574001dbe8cd81cb3005c9cac69ae05655d416cd53bedd27142235ad5743e9f26b66ac8643d859d0c8caf149a700"
19
}
20
}
Copied!
ETH Signature
Message Template
Message Example
Signature
1
RemoveLiquidity {readableLiquidityAmount} {pairSymbol}
2
Minimum: {readableAmontAMin} {tokenASymbol} {readableAmontBMin} {tokenBSymbol}
3
To: {pairAddress}
4
ChainId {chainId}
5
Nonce: {nonce}
6
Fee: {readableFee} {feeTokenSymbol}
7
Account Id: {accountId}
Copied!
1
RemoveLiquidity 0.16093570781 liquidity_0_10
2
Minimum: 0.0024884981284 ETH 9.482735746 ZKS
3
To: 0xaa45c964e21eafb38574e9d000adbaf85acfbb80
4
Chain Id: 11
5
Nonce: 5
6
Fee: 0.0 ZKS
7
Account Id: 1338
Copied!
1
{
2
"type": "EthereumSignature",
3
"signature": "0x85ce1409808a56b4522b6787d397d4b5d04a926e701a72b1388fff74f447650b1789c6bb7487b638bb1f6100faaa318b37311d831f07252bd0971331e61b8ad51b"
4
}
Copied!
Last modified 6mo ago