Usage Guide
We present here an overview of the basic wallet operations. Language-specific samples are provided in step-by-step guides.
The covered basic operations are:
Wallet management
Creating a new multi-coin wallet
Importing a multi-coin wallet
Address derivation (receiving)
Generating the default address for a coin
Generating an address using a custom derivation path (expert)
Transaction signing (e.g. for sending)
For the examples we use Bitcoin, Ethereum and Binance Coin as sample coins/blockchains.
Note: Wallet Core does not cover communication with blockchain networks (nodes): address derivation is covered, but address balance retrieval not; transaction signing is covered, but broadcasting transactions to the network not.
In this guide we use small code examples from a Swift sample application, but the focus is on the explanations.
Wallet Management
Multi-Coin Wallet
The Multi-Coin Wallet is a structure allowing accounts for many coins, all controlled by a single recovery phrase. It is a standard HD Wallet (Hierarchically Derived), employing the standard derivation schemes, interoperable with many other wallets: BIP39 for recovery phrase, BIP44/BIP84 for account derivation.
Creating a New Multi-Coin Wallet
When a new wallet is created, a new seed (and thus recovery phrase) is chosen at random. After creation, the user has to be informed and guided to backup the recovery phrase.
The random generation employs secure random generation, as available on the device.
Input parameter | Description |
---|---|
strength | The strength of the secret seed. Higher seed means more information content, longer recovery phrase. Default value is 128, but 256 is also possible. |
passphrase | Optional passphrase, used to scramble the seed. If specified, the wallet can be imported and opened only with the passphrase (Not to be confused with recovery phrase). |
Importing a Multi-Coin Wallet
A previously created wallet can be imported using the recovery phrase. Typical usecases for import are:
re-importing a wallet later, into a later installation, or
importing into another device, or
importing into another wallet app.
If the wallet was created with a passphrase, it is also required.
Input parameter | Description |
---|---|
mnemonic | a.k.a. recovery phrase. The string of several words that was used to create the wallet. |
passphrase | Optional passphrase, used to encrypt the seed. |
Account Address Derivation
Each coin needs a different account, with matching address. Addresses are derived from the multi-coin wallet. Derivation is based on a derivation path, which is unique for each coin, but can have other parameters as well. Each coin has a default derivation path, such as "m/84'/0'/0'/0/0"
for Bitcoin and "m/44'/60'/0'/0/0"
for Ethereum.
Generating the Default Address for a Coin
The simplest is to get the default address for a coin -- this requires no further inputs. The address is generated using the default derivation path of the coin.
For example, the default BTC address, derived for the wallet with the mnemonic shown above, with the default BTC derivation path (m/84'/0'/0'/0/0
) is: bc1qpsp72plnsqe6e2dvtsetxtww2cz36ztmfxghpd
. For Ethereum, this is 0xA3Dcd899C0f3832DFDFed9479a9d828c6A4EB2A7
.
Here is the sample code fort obtaining the default address for different coins:
Generating an Address Using a Custom Derivation Path (Expert)
It is also possible to derive addresses using custom derivation paths. This can be done in two steps: first a derived private key is obtained, then an address from it.
Warning: use this only if you are well aware of the semantics of the derivation path used!
Security Warning: if secrets such as private keys are handled by the wallet, even if for a short time, handle with care! Avoid any risk of leakage of secrets!
For example, a second Ethereum address can be derived using the custom derivation path ”m/44'/60’/1’/0/0”
(note the 1 in the third position), yielding address 0x68eF4e5660620976a5968c7d7925753D3Cc40809
.
Transaction Signing
In general, when creating a new blockchain transaction, a wallet has to:
Put together a transaction with relevant fields (source, target, amount, etc.)
Sign the transaction, using the account private key. This is done by Wallet Core.
Send to a node for broadcasting to the blockchain network.
The exact fields needed for a transaction are different for each blockchain. In Wallet Core, signing input and output parameters are typically represented in a protobuf message (internally needed for serialization for passing through different language runtimes).
A generic, coin-independent signer also exists (AnySigner), but its usage is recommended only in browser-based applications.
Bitcoin Transaction Signing
Bitcoin is the first UTXO
(Unspent Transaction Output) based cryptocurrency / blockchain, if you haven't read the documentation about Bitcoin, we highly recommend you to read developer glossary and raw transaction format, these will help you understand how to sign a Bitcoin transaction. Wallet Core supports Bitcoin, Bitcoin Cash, Zcash, Decred and a few forks.
The most important models in Swift are BitcoinSigningInput
and BitcoinUnspentTransaction
BitcoinSigningInput
Field | Sample value | Description |
---|---|---|
hash_type | BitcoinSigHashType.all | Bitcoin Cash needs to |
amount | 10000 | Amount (in satoshi) to send (value of new UTXO will be created) |
byteFee | 1 | Transaction fee is |
toAddress | bc1q03h6k5lt6pzfjaanz5mlnmuc7aha2t3nkz7gh0 | Recipient address (Wallet Core will build lock script for you) |
changeAddress | 1AC4gh14wwZPULVPCdxUkgqbtPvC92PQPN | Address to receive changes, can be empty if you sweep a wallet |
privateKey | [Data(...), Data(...)] | Private keys for all the input UTXOs in this transaction |
scripts | [ | Redeem scripts indexed by script hash, usually for |
utxo | [BitcoinUnspentTransaction] | All the input UTXOs, see below table for more details |
useMaxAmount | false | Consume all the input UTXOs, it will affect fee estimation and number of output |
coinType | 145 | SLIP44 Index coin type, default is 0 / Bitcoin |
BitcoinUnspentTransaction
Field | Sample value | Description |
---|---|---|
outPoint | BitcoinOutPoint(hash:index:) | Refer to a particular transaction output, consisting of a 32-byte TXID and a 4-byte output index number (vout) |
amount | 10000 | A value field for transferring zero or more satoshis |
script | 0x76a9146cfa0e96c34fce09c0e4e671fcd43338c14812e588ac | A script (ScriptPubKey) included in outputs which sets the conditions that must be fulfilled for those satoshis to be spent |
Here is the Swift sample code for signing a real world Bitcoin Cash transaction
It's worth to note that you can also calcuate fee and change manually (by using a BitcoinTransactionPlan
struct)
Below is another real world Zcash transparent transaction demonstrate this
Besides orignal Bitcoin RPC, there are many other APIs / block explorer can get UTXO and broadcast raw transaction, like: insight api, trezor blockbook, blockchain com, blockchair api.
Ethereum Transaction Signing
A simple Ethereum send transaction needs the following fields:
Field | Sample value | Description |
---|---|---|
chainID | 1 | Network selector, use 1 for mainnet (see https://chainid.network for more) |
nonce | 1 | The count of the number of outgoing transactions, starting with 0 |
gasPrice | 3600000000 | The price to determine the amount of ether the transaction will cost |
gasLimit | 21000 | The maximum gas that is allowed to be spent to process the transaction |
to | <address> | The account the transaction is sent to, if empty, the transaction will create a contract |
value | 100000000 | The amount of ether to send |
data | Could be an arbitrary message or function call to a contract or code to create a contract |
Several parameters, like the current nonce and gasPrice values can be obtained from Ethereum node RPC calls (see https://github.com/ethereum/wiki/wiki/JSON-RPC, e.g., eth_gasPrice).
Code example to fill in the signer input parameters:
Then Signer is invoked, and the signed and encoded output retrieved:
For more details on Ethereum transactions, check the Ethereum documentation. A few resources are here:
https://medium.com/@codetractio/inside-an-ethereum-transaction-fa94ffca912f
https://kauri.io/article/7e79b6932f8a41a4bcbbd194fd2fcc3a/v2/ethereum-101-part-4-accounts-transactions-and-messages
https://github.com/ethereumbook/ethereumbook/blob/develop/06transactions.asciidoc
Binance Chain (BNB) Transaction Signing
Binance Chain is built upon cosmos-sdk, instead of Message
, transaction in Binance Chain is called Order
, Binance.proto shows all the orders that Wallet Core currently supports.
To sign a order, you need to use BinanceSigningInput
:
Field | Sample value | Description |
---|---|---|
chainID | Binance-Chain-Nile | Network id, use Binance-Chain-Tigris for mainnet (see node-info api) |
accountNumber | 51 | On chain account number. (see account api) |
sequence | 437412 | Order sequence starting from 0, always plus 1 for new order from account api |
source | 0 | BEP10 source id |
sendOrder | <sendOrder> | SendOrder contains |
A Swift sample code send order is shown below:
For more details please check the Binance Chain documentation:
https://docs.binance.org/encoding.html
https://docs.binance.org/api-reference/dex-api/paths.html#http-api
Consult the complete sample applications for more details.
Last updated