# Getting started
- Connect to the zkSync network.
- Deposit assets from Ethereum into zkSync.
- Make transfers.
- Withdraw funds back to Ethereum mainnet (or testnet).
# Adding zkSync Swift SDK as a dependency
# CocoaPods
pod 'ZKSync'
# Swift Package Manager
- In Xcode go to
File -> Swift Packages -> Add Package Dependency.... - Insert
https://github.com/zksync-sdk/zksync-swift.gitinEnter package repository URLfield and press Enter. - In
Rulessetmasteras a default branch.
# Creating signers
Using seed bytes (like MNEMONIC phrase). Must have length >= 32
let zkSigner = try ZkSigner(seed: seed)
Using raw private key
let privateKey = Data(hex: "0x...")
let zkSigner = try ZkSigner(rawPrivateKey: privateKey)
Using EthSigner (explained below). The private key used by ZkSigner is implicitly derived from Ethereum signature of a special message.
let ethSigner = ...
let zkSigner = try ZkSigner(ethSigner: ethSigner, chainId: .goerli)
In case of interacting with Ethereum network like Deposit or onchain Withdraw and for creating ZkSigner you may need
to create EthSigner.
let ethSigner = try DefaultEthSigner(privateKey: "0x...")
// or from Mnemonic
let ethSigner = try DefaultEthSigner(mnemonic: "some mnemonic phrase")
# Connecting to zkSync network
For interact with both zkSync and Ethereum networks you need to create providers with endpoints to blockchain nodes
# zkSync provider
Library has predefined URLs for the next networks ChainId.Mainnet,ChainId.Goerli that
officially supports by MatterLabs. Also you can use local node for testing ChainId.Localhost set to
http://127.0.0.1:3030
let provider = DefaultProvider(chainId: .goerli)
You can create Provider with any custom URL, just use HTTPTransport for DefaultProvider
let transport = HTTPTransport(networkURL: "http://127.0.0.1:3030")
let provider = DefaultProvider(transport: transport)
# Ethereum provider
For onchain operation in Ethereum network you may create EthereumProvider using method createEthereumProvider of
Wallet
let wallet = ...
let ethereum = try wallet.createEthereumProvider(web3: Web3.InfuraGoerliWeb3())
# Creating a Wallet
To control your account in zkSync, use the Wallet. It can sign transactions with keys stored in ZkSigner and
EthSigner and send transaction to zkSync network using Provider.
let ethSigner = ...
let zkSigner = ...
let wallet = try DefaultWallet(ethSigner: ethSigner, zkSigner: zkSigner, provider: DefaultProvider(chainId: .goerli))
For onchain operations you can create Ethereum provider from Wallet
let wallet = ...
let ethereum = try wallet.createEthereumProvider(web3: Web3.InfuraGoerliWeb3())
# Depositing assets from Ethereum into zkSync
Let's try to deposit 1.0 ETH to our zkSync account.
let ethSigner = ...
let ethereum = ...
let amount = Web3.Utils.parseToBigUInt("1", units: .eth)!
firstly {
ethereum.deposit(token: .ETH, amount: amount, userAddress: self.ethSigner.address)
}.done { result in
print("Successfully performed deposit with result: \(result)")
}.catch { error in
print("Failed with error: \(error)")
}
# Checking your zkSync balance
You should be want to check your balance in zkSync network after deposit.
firstly {
wallet.getAccountStatePromise()
}.done { (state) in
let balance = state.committed.balances["ETH"] ?? "0"
print("Balance: \(balance)")
}.catch { (error) in
print("Failed with error: \(error)")
}
# Unlocking zkSync account
To make any transaction in zkSync network, you must register your ZkSigner's public key to your account provided EthSigner.
let wallet = ...
firstly {
wallet.getAccountStatePromise()
}.then { state in
wallet.provider
.transactionFeePromise(for: .changePubKey, address: wallet.address, tokenIdentifier: Token.ETH.address)
.map { ($0, state) }
}.then { (feeDetails, state) -> Promise<String> in
let fee = TransactionFee(feeToken: Token.ETH.address,
fee: feeDetails.totalFeeInteger)
return wallet.setSigningKeyPromise(fee: fee,
nonce: state.committed.nonce,
onchainAuth: false)
}.done { hash in
print("Successfully submitted transaction with hash: \(hash)")
}.catch { error in
print("Failed to submit transaction with error: \(error)")
}
# Making transfer funds in zkSync
Now after Deposit and Unlocking your account you can create second account and transfer some funds to it.
Note that we can send assets to any fresh Ethereum account, without preliminary registration!
We're going to transfer 0.1 ETH
let receiver = "0x..."
let wallet = ...
let amount = Web3.Utils.parseToBigUInt("1000000", units: .Gwei)!
firstly {
wallet.getAccountStatePromise()
}.then { state in
wallet.provider.transactionFeePromise(for: .transfer,
address: receiver,
tokenIdentifier: Token.ETH.address).map { ($0, state) }
}.then { (feeDetails, state) -> Promise<String> in
let fee = TransactionFee(feeToken: Token.ETH.address,
fee: feeDetails.totalFeeInteger)
return wallet.transferPromise(to: receiver,
amount: amount,
fee: fee,
nonce: nil)
}.done { hash in
print("Successfully submitted transaction with hash: \(hash)")
}.catch { error in
print("Failed to submit transaction with error: \(error)")
}
# Withdrawing funds back to Ethereum
All (or part of) your funds can be withdrawn back to any yours account in Ethereum.
let wallet = ...
let amount = Web3.Utils.parseToBigUInt("1000", units: .Gwei)!
firstly {
wallet.getAccountStatePromise()
}.then { state in
wallet.provider.transactionFeePromise(for: .withdraw, address: wallet.address,
tokenIdentifier: Token.ETH.address).map { ($0, state) }
}.then { (feeDetails, state) -> Promise<String> in
let fee = TransactionFee(feeToken: Token.ETH.address,
fee: feeDetails.totalFeeInteger)
return wallet.withdrawPromise(ethAddress: state.address,
amount: amount,
fee: fee,
nonce: state.committed.nonce,
fastProcessing: false)
}.done { hash in
print("Successfully submitted transaction with hash: \(hash)")
}.catch { error in
print("Failed to submit transaction with error: \(error)")
}