Link a Finality Provider EOTS PK to your BABY Address
Before proceeding with this guide, please make sure you sign the terms first.
Proof-of-Possession (PoP) establishes ownership of both your finality provider’s EOTS key and your BABY address. For finality providers, the EOTS key is essentially a Schnorr key, which should have received delegations from the phase-1 network.
This guide demonstrates how to generate PoP, validate it, submit it to the API, and remove it if you need to bond your EOTS key to a different BABY address.
This guide assumes that you have created a Babylon address to receive the airdrop using the Babylon Address CLI Creation guide. Please ensure that you have access to your keyring before proceeding.
PoP format for finality providers
The Airdrop API requires the following JSON message format of a PoP for finality providers
{
"eotsPublicKey": "3d0bebcbe800236ce8603c5bb1ab6c2af0932e947db4956a338f119797c37f1e",
"babyPublicKey": "A0V6yw74EdvoAWVauFqkH/GVM9YIpZitZf6bVEzG69tT",
"babySignEotsPk": "AOoIG2cwC2IMiJL3OL0zLEIUY201X1qKumDr/1qDJ4oQvAp78W1nb5EnVasRPQ/XrKXqudUDnZFprLd0jaRJtQ==",
"eotsSignBaby": "pR6vxgU0gXq+VqO+y7dHpZgHTz3zr5hdqXXh0WcWNkqUnRjHrizhYAHDMV8gh4vks4PqzKAIgZ779Wqwf5UrXQ==",
"babyAddress": "bbn17ew0he6svxrqj2c7mef7qsyg0assc2upa5gy7w"
}
Detailed specification of each field:
eotsPublicKey
: The EOTS public key of the finality provider in hex format.babyPublicKey
: The Babylon secp256k1 public key in base64 format.babyAddress
: The BABY account address (bbn1..
). The address is derived from thebabyPublicKey
and used as the primary identifier on the Babylon network.eotsSignBaby
: A Schnorr signature in base64 format, created by signing thesha256(babyAddress)
with the EOTS private key.babySignEotsPk
: A signature of theeotsPublicKey
, created by the Babylon private key. This signature follows the Cosmos ADR-036 specification and is encoded in base64. The signing doc spec can be found here.
One can develop tools by themselves following the above spec, or they can use our reference implementation and follow the guidance below.
1. Create PoP
1.1. Setup the EOTS Daemon
The EOTS daemon is utilized to create and manage the EOTS key of the finality provider. If you participated as a finality provider during the first phase of the Babylon mainnet, you should have already created your EOTS keys and stored them safely following this guide.
Note that for the purposes of this guide, you will need to upgrade your eotsd
version to version v0.4.3
(previously v0.4.0
was used). To do this, please follow the instructions below.
First, download the finality provider toolset repository with git clone
git clone https://github.com/babylonlabs-io/finality-provider.git
Cloning into 'finality-provider'...
Then, checkout to the v0.4.3
release tag:
cd finality-provider # cd into the project directory
git checkout v0.4.3
Note: switching to 'v0.4.3'.
At the root of the finality provider repository install the finality provider binaries using make install.
make install
CGO_CFLAGS="-O -D__BLST_PORTABLE__" go install -mod=readonly --tags "" --ldflags '' ./...
⚠ eotsd
is part of the finality provider service suite, so running make install
also generates fpd
which is not used in this guide.
You can check if the installation succeeded by running eotsd --help
.
eotsd --help
NAME:
eotsd - Extractable One Time Signature Daemon (eotsd).
USAGE:
eotsd [global options] command [command options] [arguments...]
COMMANDS:
start Start the Extractable One Time Signature Daemon.
init Initialize the eotsd home directory.
sign-schnorr Signs a Schnorr signature over arbitrary data with the EOTS private key.
verify-schnorr-sig Verify a Schnorr signature over arbitrary data with the given public key.
pop Proof of Possession commands
help, h Shows a list of commands or help for one command
Key management:
keys Command sets of managing keys for interacting with BTC eots keys.
GLOBAL OPTIONS:
--help, -h show help
1.2. Create the Proof of Possession (PoP)
The PoP can be created and exported using the eotsd pop export
command. After which, you will need to enter passphrases for eots key and baby key consecutively.
eotsd pop export --home /path/to/eotsd/home/ --key-name <my-key-name> --keyring-backend file \
--baby-home /path/to/babylon/home/ --baby-key-name <my-baby-key-name> --baby-keyring-backend file \
--output-file /path/to/pop_fp.json
Enter keyring passphrase (attempt 1/3): # for your eots keyring
Enter keyring passphrase (attempt 1/3): # for your baby keyring
{
"eotsPublicKey": "3d0bebcbe800236ce8603c5bb1ab6c2af0932e947db4956a338f119797c37f1e",
"babyPublicKey": "A0V6yw74EdvoAWVauFqkH/GVM9YIpZitZf6bVEzG69tT",
"babySignEotsPk": "AOoIG2cwC2IMiJL3OL0zLEIUY201X1qKumDr/1qDJ4oQvAp78W1nb5EnVasRPQ/XrKXqudUDnZFprLd0jaRJtQ==",
"eotsSignBaby": "pR6vxgU0gXq+VqO+y7dHpZgHTz3zr5hdqXXh0WcWNkqUnRjHrizhYAHDMV8gh4vks4PqzKAIgZ779Wqwf5UrXQ==",
"babyAddress": "bbn17ew0he6svxrqj2c7mef7qsyg0assc2upa5gy7w"
}
This command has several flag options:
--home
specifies the home directory of the EOTS daemon in which the EOTS key created for phase-1 has been stored.--key-name
specified the name assigned to the EOTS key (is the value of the flag-key-name
specified when runningeotsd keys add --key-name ...
).--passphrase
specifies the password used to decrypt the key. The passphrase is required if it was specified when creating the EOTS keyeotsd keys add --passphrase ...
.--eots-pk
is the EOTS public key which is specified aseots_pk
in the GitHub registry for each finality provider (the-eots-pk
flag takes priority over the-key-name
flag, which requireseots.db
in the-home
directory).--keyring-backend
specifies the keyring backend. Any of[file, os, kwallet, test, pass, memory]
are available. You can find more details about the available keyring backends here. By default, thetest
keyring backend is used, although it is recommended that you use an encrypted keyring.--baby-home
specifies the location where the BABY key is stored.--baby-key-name
specifies the key name of the BABY key.--baby-keyring-backend
specifies the keyring backend of the BABY key.--output-file
specifies the file path of the raw JSON result. Note that if the flag is not specified, the JSON file won't be generated.
Please refer to the Phase-1 registration guide if you want a reminder on where you stored your EOTS home directory.
If you accidentally lost the keyring file, you can recover the keyring with the mnemonic phrases by running the eotsd keys add --recover
flag option to prompt input the mnemonic phrases and recover the key:
eotsd keys add --home /path/to/eotsd/home/ --key-name <key-name-recover> --keyring-backend file --recover
1.3. Validate the Proof of Possession (PoP)
To validate the JSON file that contains the PoP, run eotsd pop validate
command:
eotsd pop validate /path/to/pop_fp.json
Proof of Possession is valid!
If Proof of Possession is valid!
is shown, the pop is successfully validated.
1.4. Troubleshooting
Common problems and possible errors that might appear.
DB timeout
If you can’t connect to the database and get the following error:
[eotsd] failed to create db backend: timeout
You should stop the process that is keeping the .db
file locked
Config error
If there is something wrong with your current config and the following error pops up:
[eotsd] failed to load config at...
This is probably due to a new parameter appeared in the config and you could create a new default config with eotsd init ...
, just remember to update the values to your key name and directory path
2. Submit PoP via API
To register your finality provider for the airdrop (if eligible), you need to submit the previously created PoP payload to the airdrop API endpoint:
curl -X POST 'https://airdrop-api.babylon.foundation/pop/baby-eots' \
-H 'Content-Type: application/json' \
-d '{
"eotsPublicKey": "3d0bebcbe800236ce8603c5bb1ab6c2af0932e947db4956a338f119797c37f1e",
"babyPublicKey": "A0V6yw74EdvoAWVauFqkH/GVM9YIpZitZf6bVEzG69tT",
"babySignEotsPk": "AOoIG2cwC2IMiJL3OL0zLEIUY201X1qKumDr/1qDJ4oQvAp78W1nb5EnVasRPQ/XrKXqudUDnZFprLd0jaRJtQ==",
"eotsSignBaby": "pR6vxgU0gXq+VqO+y7dHpZgHTz3zr5hdqXXh0WcWNkqUnRjHrizhYAHDMV8gh4vks4PqzKAIgZ779Wqwf5UrXQ==",
"babyAddress": "bbn17ew0he6svxrqj2c7mef7qsyg0assc2upa5gy7w"
}'
In case of success, the API will return a 200 status code and the following response:
{"message": "ok"}
In the case that your EOTS key does not receive any stake/points or is otherwise not eligible, the API will return a 400 status code and the following response:
{"message":"Sorry, you are not in the FP list","code":400}
To make sure your finality provider was successfully registered, you can query it by the associated baby address and check whether your EOTS public key matches
curl -X 'GET' 'https://airdrop-api.babylon.foundation/pop/baby-eots?babyAddress=your-baby-address' -H 'accept: application/json'
The API will return the following response (formatted by jq
):
[
{
"eotsPublicKey": "289719ef19e455816e474588007f1824df7f6b1bace7decf8bb1c435e4cb849e",
"babyPublicKey": "Ax4u7IEfmG6q5Ai//uD9m9vKRdU/uhWd4GSVwxwHIYQm",
"babyAddress": "bbn1v2auyq4pwgtp3yas9fdlkzehnhefzxg7vfpfdz"
}
]
This response returns all the ETOS public keys associated with this BABY address. If there is no PoP associated with this BABY address it will return an empty slice.
3. Delete submitted PoP
If you wish to remove the BABY address associated with your finality provider, you can delete the submitted PoP and re-submit a new PoP that bonds the EOTS key to a different BABY address. Please note that this is a necessary first step if you want to change your Babylon address to a new one — i.e., you must first delete the existing association and then create a new one.
3.1. Retrieve the Deletion Message
The first step to deleting your PoP is to retrieve a message containing a custom nonce from the Babylon API. You can obtain this by calling the following endpoint (replace your-baby-address
with the BABY address used in the submitted PoP):
curl -X GET 'https://airdrop-api.babylon.foundation/pop/baby-sign-message?address=your-baby-address'
Example response in JSON format:
{"message":"Welcome to Babylon Airdrop!\\r\\nAddress: bbn1v2a65yjl5cathzl8hdysqr9xz7w503xvvu85fx\\r\\nNonce: 0f7c99f145"}
3.2. Sign the response message
To prove that you are the owner of the finality provider key that intends to delete the existing proof of possession, you need to cryptographically sign the string literal that is stored inside the message
attribute of the prior JSON response.
You can accomplish this by running eotsd pop delete
command:
eotsd pop delete --home /path/to/eotsd/home/ --key-name <my-key-name> \
--keyring-backend file --baby-home /path/to/babylon/home/ \
--baby-key-name <my-baby-key-name> --baby-keyring-backend file \
--message 'Welcome to Babylon Airdrop!\\r\\nAddress: bbn1v2a65yjl5cathzl8hdysqr9xz7w503xvvu85fx\\r\\nNonce: 0f7c99f145'
{
"eotsPublicKey": "3d0bebcbe800236ce8603c5bb1ab6c2af0932e947db4956a338f119797c37f1e",
"babyPublicKey": "A0V6yw74EdvoAWVauFqkH/GVM9YIpZitZf6bVEzG69tT",
"babySignature": "FKc2rpM30yfc6ivx40H/UXF9YM+yv6Bu0UrdpS+CZx1XGCdCAxkMewr3D786hx/YhBm3UBV8qhdPp86OTVrShw==",
"babyAddress": "bbn17ew0he6svxrqj2c7mef7qsyg0assc2upa5gy7w"
}
One additional flag to the previous eotsd pop export
is -message
, which specifies the message to be signed. In this example it would be 'Welcome to Babylon Airdrop!\\r\\nAddress: bbn1v2a65yjl5cathzl8hdysqr9xz7w503xvvu85fx\\r\\nNonce: 0f7c99f145'
.
3.3. Submit the PoP Deletion Request
The output of the eotsd pop delete
command is the payload you need to submit to the API to finalize the deletion request:
curl -X DELETE 'https://airdrop-api.babylon.foundation/pop/baby-eots' \
-H 'Content-Type: application/json' \
-d '{
"eotsPublicKey": "3d0bebcbe800236ce8603c5bb1ab6c2af0932e947db4956a338f119797c37f1e",
"babyPublicKey": "A0V6yw74EdvoAWVauFqkH/GVM9YIpZitZf6bVEzG69tT",
"babySignature": "FKc2rpM30yfc6ivx40H/UXF9YM+yv6Bu0UrdpS+CZx1XGCdCAxkMewr3D786hx/YhBm3UBV8qhdPp86OTVrShw==",
"babyAddress": "bbn17ew0he6svxrqj2c7mef7qsyg0assc2upa5gy7w"
}'
In case of success, the API will return a 200 status code and the following response:
{"message":"ok"}
To ensure deletion, getting PoP by your BABY wallet address will return an empty array:
curl -X GET 'https://airdrop-api.babylon.foundation/pop/baby-eots?babyAddress=bbn17ew0he6svxrqj2c7mef7qsyg0assc2upa5gy7w'
[]
Now, you can submit a new PoP with a new BABY key.