Create wallets and config files
Two options -- automated and manual -- to create all required configuration.
Option A: Using the quickstart script
We provide a script that automates the setup for wallets and configuration files for five validators and two users.
Before running it:
Make sure you have followed all previous setup steps.
Make sure that
~/.ipc
does not exist. The script will not override it.
From within the bitcoin-ipc
repo run:
./target/release/quickstart
If you changed the "rpcuser" and/or "rpcpassword" fields in Bitcoin Regtest, then you need to update these values in the following files:
~/.ipc/validator1/.env
~/.ipc/validator2/.env
~/.ipc/validator3/.env
~/.ipc/validator4/.env
~/.ipc/validator5/.env
~/.ipc/user1/.env
~/.ipc/user2/.env
The script prints the the IPC address (aka ETH address) and the X-Only public key of each validator and user, as well as a whitelist consisting of the first four validators (to be used when creating a subnet).
In the following demo we will use the IPC address to identify users and validators in the L2 subnet, and the X-Only public key to identify validators on the bitcoin chain.
For ease of use, you can extract the IPC address and the whitelist into env variables:
export IPC_ADDRESS_OF_VALIDATOR_1=0x27b60d9f71d6806cca7d5a92b391093fe100f8e8
export IPC_ADDRESS_OF_VALIDATOR_2=0xd9c4c92ca843a53bff146c79b5d32ca4b9321414
export IPC_ADDRESS_OF_VALIDATOR_3=0x646aed5404567ae15648e9b9b0004cbafb126949
export IPC_ADDRESS_OF_VALIDATOR_4=0xbce2f194e9628e6ae06fa0d85dd57cd5579213bf
export IPC_ADDRESS_OF_VALIDATOR_5=0xb628237ff4875b039ec1c3dedcf5fad93430ee4a
export IPC_ADDRESS_OF_USER_1=0x005e05dd763dd125473f8889726f7c305e50fcae
export IPC_ADDRESS_OF_USER_2=0xa78bc5d61e0da3c2d96e29a495f4e358d8d2218d
export WHITELIST="5f0dfed3a527ac740c7d4a594cd3aa1059a936187399fc49e3fc6ea6ae177268,851c1bda327584479e98a7c28ea7adc097d290efd105310bcf714231bb99faf4,b15f99928f2478a10c5739a03f5495d342e77352d624e7cc8ebfbded544f9ac0,b45fd52573e8e6bfe0aff82fb228e887fdd92210fe0952ae65a59080fec7e529"
The ~/.ipc
directory should have the following structure:

~/.ipc
directory after the quickstart
script Option B: Manual setup
The script performs the following steps, which you can also do manually.
Step 1: Set up Bitcoin wallets for validators and clients
Throughout the demo we will use six validators (four in the initial subnet and two to demonstrate the dynamic participation) and two clients. In this step we create the necessary bitcoin wallets for them.
In order for each validator to stake, they need to have a bitcoin wallet with enough funds in it. We'll create and fund a bitcoin wallet for each validator.
# create the wallets
bitcoin-cli loadwallet "default"
bitcoin-cli createwallet "validator1"
bitcoin-cli createwallet "validator2"
bitcoin-cli createwallet "validator3"
bitcoin-cli createwallet "validator4"
bitcoin-cli createwallet "validator5"
bitcoin-cli createwallet "user1"
bitcoin-cli createwallet "user2"
# fund the wallets
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=default getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=validator1 getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=validator2 getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=validator3 getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=validator4 getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=validator5 getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=user1 getnewaddress)"
bitcoin-cli generatetoaddress 2 "$(bitcoin-cli --rpcwallet=user2 getnewaddress)"
bitcoin-cli generatetoaddress 100 "$(bitcoin-cli --rpcwallet=default getnewaddress)"
# check balances
bitcoin-cli --rpcwallet=validator1 getbalance
bitcoin-cli --rpcwallet=validator2 getbalance
bitcoin-cli --rpcwallet=validator3 getbalance
bitcoin-cli --rpcwallet=validator4 getbalance
bitcoin-cli --rpcwallet=validator5 getbalance
bitcoin-cli --rpcwallet=user1 getbalance
bitcoin-cli --rpcwallet=user2 getbalance
All wallets should have at least 100 BTC.
After restarting
If in the future you restart bitcoind, you only have to load each wallet:
# after restarting bitcoind
bitcoin-cli loadwallet "default"
bitcoin-cli loadwallet "validator1"
bitcoin-cli loadwallet "validator2"
bitcoin-cli loadwallet "validator3"
bitcoin-cli loadwallet "validator4"
bitcoin-cli loadwallet "validator5"
bitcoin-cli loadwallet "user1"
bitcoin-cli loadwallet "user2"
Step 2: Create IPC wallets for each validator
Now each validator has personal funds on Bitcoin. We will set up an IPC wallet for each validator and each user, that is, eight IPC wallets. This wallet will be used to interact with the child subnet and, for validators, to sign multisig transactions.
for i in {1..8}; do ipc-cli wallet new --wallet-type btc; done
The btc
wallet type is similar to the pre-existing evm
wallet type, except with a technical difference (the y
coordinate of the underlying secp256k1 key has even parity), which allows the validator to use the same key to sign multisig transactions on bitcoin.
The wallet for the users can also be of wallet-type evm
. For simplicity we make it btc
so it is easier to list all balances with one command.
List and record the newly created wallets addresses and corresponding x-only public keys:
ipc-cli wallet list --wallet-type btc
Pick four validators that you want to use in the initial subnet and
Write down their IPC addresses, or set the env variables
${IPC_ADDRESS_OF_VALIDATOR_1}
, ...,${IPC_ADDRESS_OF_VALIDATOR_4}
. The IPC address is printed asAddress:
by ipc-cli and starts with0x
.Construct and write down the
validator-whitelist
(to be used in the next step) as a comma-separated list using the the x-only public keys of these four validators return by ipc-cli (printed asXonlyPubKey:
). This should look like the following. Observe that there are no empty spaces between the keys.
export WHITELIST="5f0dfed3a527ac740c7d4a594cd3aa1059a936187399fc49e3fc6ea6ae177268,851c1bda327584479e98a7c28ea7adc097d290efd105310bcf714231bb99faf4,b15f99928f2478a10c5739a03f5495d342e77352d624e7cc8ebfbded544f9ac0,b45fd52573e8e6bfe0aff82fb228e887fdd92210fe0952ae65a59080fec7e529"
Let's export the secret keys of all validators:
mkdir -p ~/.ipc/validator1/
mkdir -p ~/.ipc/validator2/
mkdir -p ~/.ipc/validator3/
mkdir -p ~/.ipc/validator4/
mkdir -p ~/.ipc/validator5/
ipc-cli wallet export --wallet-type btc --address ${IPC_ADDRESS_OF_VALIDATOR_1} --hex | tail -n 1 > ~/.ipc/validator1/validator.sk
ipc-cli wallet export --wallet-type btc --address ${IPC_ADDRESS_OF_VALIDATOR_2} --hex | tail -n 1 > ~/.ipc/validator2/validator.sk
ipc-cli wallet export --wallet-type btc --address ${IPC_ADDRESS_OF_VALIDATOR_3} --hex | tail -n 1 > ~/.ipc/validator3/validator.sk
ipc-cli wallet export --wallet-type btc --address ${IPC_ADDRESS_OF_VALIDATOR_4} --hex | tail -n 1 > ~/.ipc/validator4/validator.sk
ipc-cli wallet export --wallet-type btc --address ${IPC_ADDRESS_OF_VALIDATOR_5} --hex | tail -n 1 > ~/.ipc/validator5/validator.sk
Implementation detail: The secret keys we export here will be used in two places:
By the Fendermint docker image of each validator
By the bitcoin provider of each validator, in order to sign bitcoin transactions
Step 3: Create .env file for each validator and user
The .env
file of each validator is used by the bitcoin monitor and bitcoin provider.
Create .env for validators
Navigate to bitcoin-ipc directory and run the following commands:
cp .env.example ~/.ipc/validator1/.env
cp .env.example ~/.ipc/validator2/.env
cp .env.example ~/.ipc/validator3/.env
cp .env.example ~/.ipc/validator4/.env
cp .env.example ~/.ipc/validator5/.env
In each .env file modify the values
RPC_USER
andRPC_PASS
: Update them if you changed the default values in the bitcoin.conf file (in Bitcoin Regtest)WALLET_NAME
: Use the bitcoin wallet names created on the previous step ("validator1", ... "validator5")DATABASE_URL
: You can use<HOME_DIR>/.ipc/validator1/regtest_db
, ... ,<HOME_DIR>/.ipc/validator5/regtest_db
PROVIDER_PORT
: Use ports 3030, 3031, 3032, 3033, 3034, respectively.PROVIDER_AUTH_TOKEN
: You can usevalidator1_auth_token
, ... ,validator5_auth_token
VALIDATOR_SK_PATH
: Use<HOME_DIR>/.ipc/validator1/validator.sk
, ...,<HOME_DIR>/.ipc/validator5/validator.sk
replace
<HOME_DIR>
with your absolute home directory path.
Let's see the ~/.ipc/validator1/.env
file as an example:
# Bitcoin Core RPC
RPC_USER=user
RPC_PASS=pass
RPC_URL=http://localhost:18443
WALLET_NAME=validator1
# Validator
VALIDATOR_SK_PATH=<HOME_DIR>/.ipc/validator1/validator.sk
# Provider + Monitor
DATABASE_URL=<HOME_DIR>/.ipc/validator1/regtest_db
# Provider
PROVIDER_PORT=3030
PROVIDER_AUTH_TOKEN=validator1_auth_token
# General
RUST_LOG=bitcoin_ipc=debug,monitor=info,provider=debug,bitcoincore_rpc=error,actix_web=error
Create .env for users
Let's do the same for the users.
mkdir ~/.ipc/user1
mkdir ~/.ipc/user2
cp .env.example ~/.ipc/user1/.env
cp .env.example ~/.ipc/user2/.env
Edit the two new .env files as follows:
RPC_USER
andRPC_PASS
: Update them if you changed the default values in the bitcoin.conf file (in Bitcoin Regtest)WALLET_NAME
: Useuser1
anduser2
, respectively.DATABASE_URL
: You can use<HOME_DIR>/.ipc/user1/regtest_db
and<HOME_DIR>/.ipc/user2/regtest_db
, respectivelyPROVIDER_PORT
: Use 3040, 3041, respectivelyPROVIDER_AUTH_TOKEN
: You can useuser1_auth_token
anduser2_auth_token
, respectivelyVALIDATOR_SK_PATH
: It is irrelevant, it is only used by validatorsreplace
<HOME_DIR>
with your absolute home directory path.
Let's see the ~/.ipc/validator1/.env
file as an example:
# Bitcoin Core RPC
RPC_USER=user
RPC_PASS=pass
RPC_URL=http://localhost:18443
WALLET_NAME=user1
# Validator
# VALIDATOR_SK_PATH=
# Provider + Monitor
DATABASE_URL=/Users/orestis/.ipc/user1/regtest_db
# Provider
PROVIDER_PORT=3040
PROVIDER_AUTH_TOKEN=user1_auth_token
# General
RUST_LOG=bitcoin_ipc=trace,monitor=debug,provider=debug,bitcoincore_rpc=error,actix_web=info
Step 5: Initialise the config file for each validator and user
The config.toml
of each validator file is used by Fendermint and by ipc-cli.
Navigate to the ipc
repo and run the following.
ipc-cli --config-path ~/.ipc/validator1/config.toml config init
ipc-cli --config-path ~/.ipc/validator2/config.toml config init
ipc-cli --config-path ~/.ipc/validator3/config.toml config init
ipc-cli --config-path ~/.ipc/validator4/config.toml config init
ipc-cli --config-path ~/.ipc/validator5/config.toml config init
ipc-cli --config-path ~/.ipc/user1/config.toml config init
ipc-cli --config-path ~/.ipc/user2/config.toml config init
For each validator's and user's config file, modify:
provider_http
to match the port you set inPROVIDER_PORT
in the .env file of the validator, that is, using ports 3030, 3031, 3032, 3033, 3034 for the validators and 3040, 3041 for the user.auth_token
to match thePARENT_AUTH_TOKEN
you've set in the .env file of the validator, that is usevalidator1_auth_token
, ... ,validator5_auth_token
for validators anduser1_auth_token
, ... ,user2_auth_token
for users.
Let's see ~/.ipc/validator1/config.toml
for example. It should look similar to the following.
keystore_path = "~/.ipc"
# Bitcoin Regtest
[[subnets]]
id = "/b4"
[subnets.config]
network_type = "btc"
provider_http = "http://127.0.0.1:3030/api"
auth_token = "validator1_auth_token"
[[subnets]]
id = "/b4/t410fyi77izvsakigfjnocb7f3hm52bjdeb76jayo4ti"
[subnets.config]
network_type = "fevm"
provider_http = "http://localhost:8545/"
gateway_addr = "0x77aa40b105843728088c0132e43fc44348881da8"
registry_addr = "0x74539671a1d2f1c8f200826baba665179f53a1b7"
/b4
is the identifier for the Bitcoin regtest network.
Last updated