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 the babyPublicKey and used as the primary identifier on the Babylon network.
  • eotsSignBaby: A Schnorr signature in base64 format, created by signing the sha256(babyAddress) with the EOTS private key.
  • babySignEotsPk: A signature of the eotsPublicKey, 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 running eotsd 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 key eotsd keys add --passphrase ....
  • --eots-pk is the EOTS public key which is specified as eots_pk in the GitHub registry for each finality provider (the -eots-pk flag takes priority over the -key-name flag, which requires eots.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, the test 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.

Search Your Wallet Address Here

Wallet 1001

bbn18h7h6c3k5stu4hlhtlprthnj6d6d4s83jj3zuj

Wallet 1002

bbn19sqa97sy7dtfugupa4gqtsghqe0fpqtfemftk5

Wallet 1003

bbn1kf2mpvjls584k9kkhp2qtlfvc2j7nprc8xcsrs

Wallet 1004

bbn1eeru2sxjme2dty0jf9apx5393n33rsuatfu0qy

Wallet 1005

bbn18g298cjwuu3268zx5swwwl08tljz2jqxf6le4n

Wallet 1006

bbn14v9pmkzutea6c846zvjlql0c4cxdtpsyfuw85t

Wallet 1007

bbn1th8tgcjugam0kv3zvavhll6rlf709qkd4mnmrd

Wallet 1008

bbn1hpud8k82gx6fqxfztn0ygfeszk36peqgmzm2vx

Wallet 1009

bbn1fkmtexmz7ycjqmzsj0kujpp9pzwslqhjzcc53y

Wallet 1010

bbn1x8acnllnejrj9r8qa57y8gk8wwjnl3n5xe9tjj

Wallet 1011

bbn1qjhg3m94ztp3tn4nffr02yyw24uzekv5h49he7

Wallet 1012

bbn1kn9f77wzxgp3gp65px4rnss8xuwt7dcfcj3qp4

Wallet 1013

bbn1wcjs0dqeec245zq5ul2m0kme9wh9kqmr2gpfh4

Wallet 1014

bbn1fcyt39sv3qymup5ghe0vum5e6k3z49tlmdkkym

Wallet 1015

bbn1wn579mempkjlvt9em75wn0aesufnh5xtgm8cru

Wallet 1016

bbn1v4e647v2nd88t2yneh280neh7s5fdtn296gmth

Wallet 1017

bbn1hwqphv7s0hg60vu8tkpw2uwn6dggla0hqq80s9

Wallet 1018

bbn1x3p4769xznddqlytv3jea8kpy0r9ddkwm23t7j

Wallet 1019

bbn1h6e82j6t99qn7vwdx8mqj6x8vvuc2u92q7wyhx

Wallet 1020

bbn1vpm5tzu6wll5ukrjmff9hfm0q3ykur6xjlwm4y

Wallet 1021

bbn1rwk0ld696ytzyhz4mml28nxxl8t6kgek4ga39y

Wallet 1022

bbn15lp42l5f6stsc6044qrm4znz5vasjkhxn9y03c

Wallet 1023

bbn1qj093s828v93q6tstlnkcw87fpws8680ecwkgu

Wallet 1024

bbn1qv6tnfz6lp53cen6y54emryxm5ga2kf2u9chvt

Wallet 1025

bbn1c426afcsvrurxhtwux25y9k8hvggp3lqyzs5ml

Wallet 1026

bbn1yegfhuegs090gk0u6f05stpk9gf4xnt0tur8c4

Wallet 1027

bbn1y5d6fu2h8xyxnj4pamknc4tgejcsqtrfxxq2dh

Wallet 1028

bbn18etdtxelcte23yq0axerxuz8555xkne05lmwj6

Wallet 1029

bbn187jftjj4pef27cezmg3urqasfk5rnu0332hexu

Wallet 1030

bbn1tancy895xqruw5frxtnjldvknpztu76uqf34zn

Wallet 1031

bbn14a3prpl0tqxf6kz2eu23707a5agf6c07rjlulx

Wallet 1032

bbn1kr9ydy66j633rv2vykyndrwdng7ja0u6ptkfsu

Wallet 1033

bbn1t3ugdzf0uk97kwr520rycx7g8zfu0w6jgyl59q

Wallet 1034

bbn17y5gv3h2uzxcjnmtlla0eqn7al36ru0an9r0tu

Wallet 1035

bbn1722ngxd4zm5wjwk3xuttz29kjcfkp8xpjsnwck

Wallet 1036

bbn1mtv0fkefqr9maktchhslgq0m0f2cmazwcwfldr

Wallet 1037

bbn1s4mrce2shsgp2gzkfe3rhy6fswhwdl3t0248lf

Wallet 1038

bbn1q6u4wqfyamd2mqu67mqp3fm6wszh9cv4jsve33

Wallet 1039

bbn1lwg9x6l8fa5m0xdksktej7hx3amtxkuaz42cs2

Wallet 1040

bbn1gkds95sr9rd2cep22ehgk0r5yjxf7ek3t7yaat

Wallet 1041

bbn1cz68v3vjkxsk076rp4y4yvqwv5esxva82ktwe2

Wallet 1042

bbn1tw45uhrx5c82awvjluhyaqjfehd4vguuer4m5j

Wallet 1043

bbn1fmzcvw9e0qck79xzc7jhfwwn6kl66xcelj2fcn

Wallet 1044

bbn176wupms99ly4hrh4z2fnnpmcw27largg0qkh3e

Wallet 1045

bbn1g2lftxkw5fzdg334x9w8mal2tqjmhu9u7uxpga

Wallet 1046

bbn18cfjhc82w5p3g2pk742x8n93cddh5ngtv7hmuq

Wallet 1047

bbn16fx58pm76u6xksll4f7uym80n36u5hj6pa97n8

Wallet 1048

bbn14r22mau0x0kj442g68mw3srkqllftpatyhm2j0

Wallet 1049

bbn1886nd508sy6dzgp8f40meekyt6dc3e4gfs0eyw

Wallet 1050

bbn1r7tdnm8cl0fpfc8235kg4zvehx86xmagdxn70g

Wallet 1051

bbn185e2phkzdd689ywesdx3e855lu664076y9p3tl

Wallet 1052

bbn1r3g3d64kw48cyypygqj73seyau08a8g6rj005s

Wallet 1053

bbn1pe3klwlgk88tmre30eughzr5lmznje2zzacaqj

Wallet 1054

bbn1pcvkrx84x02smykvhyyp29y678wz8m7a438cea

Wallet 1055

bbn1ps0ksazr38g585r63jcvudv2ecz29zxrmmsy65

Wallet 1056

bbn15f404y73cqqvyheg7ptwl34vw4cyajyvejj9sn

Wallet 1057

bbn1s2z3fupjjwzkews9rv8wyc4759wk2fmajjah63

Wallet 1058

bbn1cc9vy5k3d3cshp6cq53nuazp68wyzz0kw4zls8

Wallet 1059

bbn179ek2eghxmesvj28jay4qepkgjy7gc06qquprx

Wallet 1060

bbn1e2arzngcsh0dmadj3rheazvyz380y7epjnq75j

Wallet 1061

bbn1mf2xcyfn6cyw8het2kdm358y85mksafmk8nasn

Wallet 1062

bbn1lf7tfh3sku5jk7pzd20ekjjvx8wtjerxyy3ac8

Wallet 1063

bbn1m0n8c5ph95tjwhewxyfmsf2twe58lfeg20qttd

Wallet 1064

bbn108dr63ml598ple4hjnes4adj50jxe99qv4zyef

Wallet 1065

bbn1nyw2qyhadzpte8vs4fwv6g92qjp7wqavhcmv69

Wallet 1066

bbn1nzutfxw2xytwat3udz59htms4q06mr6ftdsl2z

Wallet 1067

bbn1dw7sllq6t7erdn7vpzuv0tc009884tacqpaf80

Wallet 1068

bbn1sl503szjy2wgy7wp6ttx0q666ev3a8l5qzycvm

Wallet 1069

bbn1fc4vvwuvmm2nl7w32rca4gqkzfhk309kyeskd9

Wallet 1070

bbn1t3tqvh5c38quy5a5pnyu8e4d0lm8ukdfk2erjw

Wallet 1071

bbn1kgawj8s68d0wq5tzzty3hhszecepd3tpmkecd9

Wallet 1072

bbn1afmqn4jn2f0f5antzslwu6urcaqdh68tw7r7w2

Wallet 1073

bbn19f496tt55sy5cz840u2c3l3ncgkp64gwt98wjg

Wallet 1074

bbn14jcgsf4fulm8phpy37lp35cup3cdx50vkrvej5

Wallet 1075

bbn1awdvgc6q0ffjyajhnle0kyqa3tu3g5ws38nl5l

Wallet 1076

bbn16k3dxfdmgdwas6z9z0q5pa3e27d0yfww5pr5zl

Wallet 1077

bbn18zgecrnhz0au8lzyt7g28gzsj7cvp6vl8sa7c4

Wallet 1078

bbn147qv538fy0sw74h5dx650az78tlun4tma65u6d

Wallet 1079

bbn1qwsxj7e7vp8pt7lklrqtqslm2c9wqr0kguy2zk

Wallet 1080

bbn1d2p4pcw74cquw8gclgq6s4ly8kmnwj2ndjy92j

Wallet 1081

bbn15cc3ua92934x7pr0djkqpt2tk9xr754gamzk9j

Wallet 1082

bbn1cxs9hs54p8vnl2ptagwc4zfuf8rtty287w4j5j

Wallet 1083

bbn1f2y0llj5lprcux2zdr3vq4djd60h4pk7y45z8e

Wallet 1084

bbn19v4g649mahtgqnzgjx45jnz5lvd9qhs7jqptyl

Wallet 1085

bbn107qdsnt4hnd9rmhaeum3etyfyd4rgu6hzpxjgd

Wallet 1086

bbn14fz9em60c8ev4t65nnk6h53qflchhld2l47cv2

Wallet 1087

bbn10w0cq4s7zz02gwygmeydt89vha7z3wryctxzmr

Wallet 1088

bbn1rz5u93fgth3mpcnrs995wn5nuwy0ts9quxm72m

Wallet 1089

bbn1am2glrtt9mf3rndl4zgwc5hnewqamy7q309av5

Wallet 1090

bbn1p69p9peq5n507tjp755zayu3fgya0hg6vm7vt8

Wallet 1091

bbn1ypwfxjgleex0m2wa60jfhfzrc037qp7rjmf32r

Wallet 1092

bbn1xpuqpfxtsdh90tl6aeh3c6e62tnd9em4ztnyyu

Wallet 1093

bbn1at6r5dzkzs7uj2lmfr40qrmrnzvz263q2e5r2v

Wallet 1094

bbn1dzdzxyyvq7g4w7vamxek22hclfh9rshcvs93tk

Wallet 1095

bbn1zlnvltl3zj756txjg4j953e9jghakuukdeppgz

Wallet 1096

bbn17q9agf0mvmpdgh4l0k59vx8026tjja7zxdpd97

Wallet 1097

bbn1mml8sp4xskpm7ywmy5hv237w4t2t5dhlz7cucs

Wallet 1098

bbn1vljm3clt6zejsc2nw3rsn9ny8p8jhmm99vhzc5

Wallet 1099

bbn1vr8xv4wa3a8msel052jnaqu7z3hh6fd90c63vx

Wallet 1100

bbn1tjzhpk4e70n2hf5ykul2dj8ykj8venyvawp9lt