Link a BTC PK to Your BABY Address

Before proceeding with this guide, please make sure you sign the terms first.

The Proof-of-Possession (PoP) establishes ownership of both your BTC key and BABY address. For BTC stakers, the BTC key refers to the Schnorr key that signs the staking transaction.

This guide demonstrates how to generate the PoP, validate it, submit it to the airdrop API, and remove it if you need to link your BTC 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 BTC stakers

The Airdrop API requires the following JSON message format of a PoP for btc stakers:

{
    "babyAddress": "bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424",
    "btcAddress": "bc1qcpty6lpueassw9rhfrvkq6h0ufnhmc2nhgvpcr",
    "btcPublicKey": "79f71003589158b2579345540b08bbc74974c49dd5e0782e31d0de674540d513",
    "btcSignBaby": "AkcwRAIgcrI2IdD2JSFVIeQmtRA3wFjjiy+qEvqbX57rn6xvWWECIDis7vHSJeR8X91uMQReG0pPQFFLpeM0ga4BW+Tt2V54ASEDefcQA1iRWLJXk0VUCwi7x0l0xJ3V4HguMdDeZ0VA1RM=",
    "babySignBtc": "FnYTm9ZbhJZY202R9YBkjGEJqeJ/n5McZBpGH38P2pt0YRcjwOh8XgoeVQTU9So7/RHVHHdKNB09DVmtQJ7xtw==",
    "babyPublicKey": "Asezdqkvh+kLbuD75DirSwi/QFbJjFe2SquiivMaPS65"
}

Detailed specification of each field:

  • babyAddress: The Bech-32 encoded BABY address.
  • btcAddress: The Bech-32 encoded address of the staker BTC key used in phase-1 staking.
  • btcPublicKey: The hex encoded staker public key used.
  • btcSignBaby: The Base64 encoded BIP322 signature made using the key corresponding to the  btcAddress.
  • babySignBtc: The Base64 encoded ADR36 signature made using the key corresponding to the babyPublicKey. The signing doc spec can be found here.
  • babyPublicKey: The Base64 encoded Babylon public key corresponding to the babyAddress.

You have the option to either develop your own tooling following the above specification or use our reference implementation following the rest of the guide.

1. Generate PoP

1.1. Prepare the BTC wallet

We'll use the bitcoind wallet to demonstrate how to prepare your BTC wallet.

Launch your bitcoind instance and load the wallet you used for phase-1 staking (see instructions for bitcoind setup for phase-1):

bitcoin-cli -rpcuser=user -rpcpassword=pass loadwallet "walletName"

where:

  • rpcuser=user specifies the username for bitcoind RPC access.
  • rpcpassword=pass specifies the password for bitcoind RPC access.
  • loadwallet "walletName" specifies the name of wallet used in phase-1 staking.

1.2. Setup the stakercli

The stakercli program facilitates communication between your BABY keyring and bitcoind wallet to create a valid PoP payload.

First, clone the btc-staker repository:

git clone https://github.com/babylonlabs-io/btc-staker.git
Cloning into 'btc-staker'...

Next, checkout to the v0.15.2 release tag:

cd btc-staker
git checkout v0.15.2

In the root directory of btc-staker, install the binaries using make install:

make installCGO_CFLAGS="-O -D__BLST_PORTABLE__" go install -mod=readonly --tags "" --ldflags ''  ./...

Verify the installation by running stakercli --help.

make install
CGO_CFLAGS="-O -D__BLST_PORTABLE__" go install -mod=readonly --tags "" --ldflags ''  ./...

Verify the installation by running stakercli --help.

stakercli  --help
NAME:
   stakercli - Bitcoin staking controller
USAGE:
   stakercli [global options] command [command options] [arguments...]
COMMANDS:
   help, h  Shows a list of commands or help for one command
   Admin:
     admin, ad  Different utility and admin commands
   Daemon commands:
     daemon, dn  More advanced commands which require staker daemon to be running.
   PoP commands:
     pop  Commands realted to generation and verification of the Proof of Possession
   transaction commands:
     transaction, tr  Commands related to Babylon BTC transactions Staking/Unbonding/Slashing
GLOBAL OPTIONS:
   --btc-network value            Bitcoin network on which staking should take place (default: "testnet3")
   --btc-wallet-host value        Bitcoin wallet rpc host (default: "127.0.0.1:18554")
   --btc-wallet-rpc-user value    Bitcoin wallet rpc user (default: "user")
   --btc-wallet-rpc-pass value    Bitcoin wallet rpc password (default: "pass")
   --btc-wallet-passphrase value  Bitcoin wallet passphrase
   --help, -h                     show help

1.3. Create PoP

You can create and export the PoP using the stakercli pop gcp command:

stakercli pop gcp --btc-address bc1qcpty6lpueassw9rhfrvkq6h0ufnhmc2nhgvpcr \
   --baby-address bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424 \
   --keyring-dir /path/to/babylon/keyring \
   --keyring-backend file --btc-wallet-host localhost:8332 \
   --output-file /path/to/pop.json
Enter keyring passphrase (attempt 1/3):
{
    "babyAddress": "bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424",
    "btcAddress": "bc1qcpty6lpueassw9rhfrvkq6h0ufnhmc2nhgvpcr", 
    "btcPublicKey": "79f71003589158b2579345540b08bbc74974c49dd5e0782e31d0de674540d513",
    "btcSignBaby": "AkcwRAIgcrI2IdD2JSFVIeQmtRA3wFjjiy+qEvqbX57rn6xvWWECIDis7vHSJeR8X91uMQReG0pPQFFLpeM0ga4BW+Tt2V54ASEDefcQA1iRWLJXk0VUCwi7x0l0xJ3V4HguMdDeZ0VA1RM=",
    "babySignBtc": "FnYTm9ZbhJZY202R9YBkjGEJqeJ/n5McZBpGH38P2pt0YRcjwOh8XgoeVQTU9So7/RHVHHdKNB09DVmtQJ7xtw==",
    "babyPublicKey": "Asezdqkvh+kLbuD75DirSwi/QFbJjFe2SquiivMaPS65"
}

When --output-file is specified, this command generates a JSON file containing the PoP result at the specified path. Here are the available flag options:

  • --btc-address is the Bech-32 encoded address of the BTC key used in phase-1 staking.
  • --baby-address is the Bech-32 encoded BABY address.
  • --keyring-dir is the directory on which the BABY key that will receive the airdrop is stored. Note that this should not contain the direct parent directory of the key files (e.g., keyring-xxx). For example, if the keyring file is stored under ~/.babylond/keyring-file/, then ~/.babylond/ should be specified in the flag.
  • --keyring-backend is the backend of the BABY key. It should be the same as the one when the key was created.
  • --btc-wallet-host is the host of the BTC wallet. The default for BTC mainnet is localhost:8332.
  • --btc-wallet-rpc-user Bitcoin wallet rpc user (default: user). Specify if needed.
  • --btc-wallet-rpc-pass Bitcoin wallet rpc password (default: pass). Specify if needed.
  • --btc-wallet-passphrase Bitcoin wallet passphrase. Specify if needed.
  • --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.

1.4. Validate PoP

To validate the JSON file that contains the PoP, run stakercli pop validate command:

stakercli pop validate /path/to/pop.json
Proof of Possession is valid!

2. Submit PoP via API

To register your staker’s information 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-btc' \
-H 'Content-Type: application/json' \
-d '{
    "babyAddress": "bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424",
    "btcAddress": "bc1qcpty6lpueassw9rhfrvkq6h0ufnhmc2nhgvpcr",
    "btcPublicKey": "79f71003589158b2579345540b08bbc74974c49dd5e0782e31d0de674540d513",
    "btcSignBaby": "AkcwRAIgcrI2IdD2JSFVIeQmtRA3wFjjiy+qEvqbX57rn6xvWWECIDis7vHSJeR8X91uMQReG0pPQFFLpeM0ga4BW+Tt2V54ASEDefcQA1iRWLJXk0VUCwi7x0l0xJ3V4HguMdDeZ0VA1RM=",
    "babySignBtc": "FnYTm9ZbhJZY202R9YBkjGEJqeJ/n5McZBpGH38P2pt0YRcjwOh8XgoeVQTU9So7/RHVHHdKNB09DVmtQJ7xtw==",
    "babyPublicKey": "Asezdqkvh+kLbuD75DirSwi/QFbJjFe2SquiivMaPS65"
}'

In case of success, the API will return a 200 status code and the following response:

{"message":"ok"}

In the case that your staker key does not have 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 staker list","code":400}

To make sure your staker key was successfully registered, you can query it by the associated baby address and check whether your staker public key matches

curl -X 'GET' 'https://airdrop-api.babylon.foundation/pop/baby-btc?babyAddress=your-baby-address' -H 'accept: application/json'

The API will return the following response (formatted by jq):

[
  {
    "babyAddress": "bbn1kg3hw2trn4lpv4kg92tafqpwq4lpea2ep5d9r4",
    "btcAddress": "bc1prfh4v3j0p9p66qzj79qe3p08q4gfntmsm7j4zehdq2ks0tn050yqczwlnt",
    "btcPublicKey": "7e0c0bee635c97dc877a2ec5f55f0c9f2d1620ee032c1823f204fe5c64b6613a",
    "babyPublicKey": {
      "type": "tendermint/PubKeySecp256k1",
      "value": "A7pgdC3q+IOeeavUqdhYpupU2U/qL+kEu0wDxXLhFs6m"
    }
  }
]

This response returns all the staker public keys associated with this BABY address. If there is no Proof of Possession 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 BTC key, you can delete the submitted PoP and re-submit a new PoP that bonds the BTC staker to a different BABY address. Please note that this is a necessary first step if you want to change your BABY 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 ownership of the staker key that intends to delete the existing PoP, you need to cryptographically sign the entire string literal found in the message attribute of the previous JSON response.

You can accomplish this by running stakercli pop gdp command:

stakercli pop gdp --btc-address bc1qrxxqcyf7deu669wku78np3nzyg5jdnegvpg9lt \
  --baby-address bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424 \
  --keyring-dir /path/to/babylon/keyring \
  --keyring-backend file \
  --msg='Welcome to Babylon Airdrop!\\r\\nAddress: bbn1v2a65yjl5cathzl8hdysqr9xz7w503xvvu85fx\\r\\nNonce: 0f7c99f145'
Enter keyring passphrase (attempt 1/3):
{
    "babyAddress": "bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424",
    "babySignature": "adEjxmRv+ujogTKt5Vnngo8BLatv+e0Xqs4KQzQm+gEUCTe8c4pXNAfYa5UMaEI0pbkqD5qKAo++LBbxVz/kkA==",
    "babyPublicKey": "Asezdqkvh+kLbuD75DirSwi/QFbJjFe2SquiivMaPS65",
    "btcAddress": "bc1qrxxqcyf7deu669wku78np3nzyg5jdnegvpg9lt"
}

where:

  • --msg is the message received from the API. It is important that string is closed in single quotes.
  • --keyring-dir is where the BABY key is stored.
  • --keyring-backend is the backend of the BABY key. It should be the same as the one when the key is created.
  • --btc-address is the address of the BTC key used in phase-1 staking. Bech-32 encoded.
  • --baby-address is the address derived from the BABY key used in a submitted PoP. Bech-32 encoded.

3.3. Submit the PoP Deletion Request

The output of the stakercli pop gdp command is the payload you need submit to the API in order to finalize the deletion request:

curl -X DELETE 'https://airdrop-api.babylon.foundation/pop/baby-btc' \
-H 'Content-Type: application/json' \
-d '{
    "babyAddress": "bbn1xjz8fs9vkmefdqaxan5kv2d09vmwzru7jhy424",
    "babySignature": "adEjxmRv+ujogTKt5Vnngo8BLatv+e0Xqs4KQzQm+gEUCTe8c4pXNAfYa5UMaEI0pbkqD5qKAo++LBbxVz/kkA==",
    "babyPublicKey": "Asezdqkvh+kLbuD75DirSwi/QFbJjFe2SquiivMaPS65",
    "btcAddress": "bc1qrxxqcyf7deu669wku78np3nzyg5jdnegvpg9lt"
}'

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-btc?babyAddress=your-baby-address'
[]

Now, you can submit a new PoP with a new BABY address.

Search Your Wallet Address Here

Wallet 801

bbn15npz2ymzp8ac9jm2j53au4zgtn5mf0j0hdzngz

Wallet 802

bbn1839mdqfelegdulfx6lvpl0qncnpsvwn0ne8wey

Wallet 803

bbn1tfa0pa54ttea8zfxutcpz2m9zxc6km2r958500

Wallet 804

bbn1957ecg0ue2auj98c24nu6w70jyjpt78szy490j

Wallet 805

bbn14v7m7ef6dl0k4h2sj4l5rmjfsww94ece64uxfl

Wallet 806

bbn1xskz36zzze2f6vcqtz5qxtfwa75qjj4ls9wr52

Wallet 807

bbn14qr8enkh925f4n0aeyv2gr3g0pk4rhuqgy9ymg

Wallet 808

bbn1hgt649d0l5vnlg4nmgvkg0h0d0tttajqnrtkv0

Wallet 809

bbn1mscmy3zvsen5m69rp8g8rre26ay7zdlat9fcj6

Wallet 810

bbn1m7dj6dw80fmgu69nc79gmkcqxmgl4d9wycrqls

Wallet 811

bbn10mxgth0v4ewmncet3nmlksha2r82464y9ky53t

Wallet 812

bbn1003028k3afsp23w4t23wnzv3j2795skkwahgxu

Wallet 813

bbn1e5df3q4rf359vr696h407dagy4enhskqupuf5j

Wallet 814

bbn1eeyxjrq2rrldcl2kh2h0dxg9sv78ksfmjvf9gu

Wallet 815

bbn1u6gmuqc6se4x2k6dy23k3q36zn0s9h50eq8mfc

Wallet 816

bbn1wyl9evzcaqzmlz9c4tlx00cz75s9r3c6j7q6jy

Wallet 817

bbn193dtjl66x4de8v6hcxjl6sxkmzjrsah9hyrlvm

Wallet 818

bbn1stuhzahha4aeqdjckkhudfj9dng7tcljyrr85l

Wallet 819

bbn1fxehpvnk63sfmmuxk0vrkfuz6xc2r4jtvajf5d

Wallet 820

bbn1j6qfnkc6gjcxtyp2m3utaycejuglfsmj7kt5dl

Wallet 821

bbn1r9t05e647w6rvd9cktfnkz3d3wtukdj8sc7z74

Wallet 822

bbn1hsl70gvlljx63rezwl5ya43lh4hm4dgtrel0vm

Wallet 823

bbn1j87dk5yklrac29sq9alzchg5g3sg8y08cxel2n

Wallet 824

bbn1hlqhemqcfvde32u393v044t37mw7m6uujvry4n

Wallet 825

bbn1dlady20pn9sxukpqj88h20dqvj2y059uc6379r

Wallet 826

bbn1r4ydzqd0255zwetyyypzg9zyynudyeh7kjdhpn

Wallet 827

bbn1pjpz6czna250t3h8dhw43ul4pxug7vzu04nqdx

Wallet 828

bbn17xrzhvtr247zq5gtfhyk029ec8x437xvae8096

Wallet 829

bbn13nv5tmmw0prt46vjm4yuusdw7y3u57zursarur

Wallet 830

bbn1fguqnsnuqx63uk9xa5p9tyc3pzyqcqnzunkqan

Wallet 831

bbn1m4w9x02yyxjgypr7hwwmhfe9722hg5ffqndyt7

Wallet 832

bbn1gwvjydrwcd7n7mqdhjdhx8pntxxwrj03pldtee

Wallet 833

bbn1xxt7pa6xqkalflp6yq76c67xnd0da6kte85r3r

Wallet 834

bbn1uqcek6m8c859wsgzds05huueq5x7eqc830tf7w

Wallet 835

bbn12fsh6v3ej8w6h2js6m8u3wn88w6e4fnteu5mzm

Wallet 836

bbn1qthsnk69pglp0mknjzak9tdh2uzrj39lgpagk3

Wallet 837

bbn1wtv4dthpjgu9qf6v58yd27cwkwgq2v33c27s5j

Wallet 838

bbn1ual350u2xd4fg2ueqlp9qedyaajsfnvmfy9pqz

Wallet 839

bbn1xdxs4tysa27cj0fmzpgq22f9whx8l2s4xgxp2t

Wallet 840

bbn1sz500hfqhhq3kj39nj0hgdys4pnkr4jzhm4cdj

Wallet 841

bbn1l8mtqc2pqv2wadp9md7hxw8j7e7ha5w6srlt0k

Wallet 842

bbn1sn497dxf0u06fh9yplhktq9j8s87xqt2q4gdwv

Wallet 843

bbn1nhyc23usgy67r8ldh7j0dna4fcnj0k4r4kh7lq

Wallet 844

bbn14ut9gva3akmpew0rzrxde926j7kapjw4n63ycj

Wallet 845

bbn1wm0ygszvumpfarjrfynywl4sw3mratez8f7xll

Wallet 846

bbn1uwqvhv7msmm2csxv72vyszvz40xxhl73ul5k02

Wallet 847

bbn1cax3n9epn3ezx7ymfzgmvzhtdy47fq78n3hw48

Wallet 848

bbn1653rp8zuw7yucnxkjjscln3nm4444spn2m6k35

Wallet 849

bbn19xgt6u8puvg7lp6acsyudtadfj680xd8umfv40

Wallet 850

bbn18khnaz0kwtm0tsuh6kpwy5z2f5nzv3whcphmwq

Wallet 851

bbn19wlxdkujqgum0agfgksqxemkmle8ypv04n5vn0

Wallet 852

bbn1qcm9hh5ckqh7mqvun8z0auhc5suayymy3r9fsj

Wallet 853

bbn1gfzx4rfhyx76v753j82npusu7zskllecfqnzuk

Wallet 854

bbn1uaheqp67qjylrx6sdakdlxj6gt0kq99gu2m3dv

Wallet 855

bbn1v5j645natsmhzzhpwv4pw4sdpfd9jdtyy4tfwl

Wallet 856

bbn1r75p3ss6cdhvvna2j9g4qkk80tst2zj4r77mth

Wallet 857

bbn1y0f5s25g3k8awf3vp60r6fk69cuyeyz9er24nc

Wallet 858

bbn196gycaf0gzmp6hv7e64u7u5fn9tkfp7llsg7h9

Wallet 859

bbn1gzxmk4n8ugcjm3wlw3ltgpqkz2fgqrslyflksp

Wallet 860

bbn1xfssvsd6atn9jy74p9lr3vt9z8tx559nsfudxk

Wallet 861

bbn1lf27njgs89v8k2yjpcsfn5um7gu0gnaztsprfj

Wallet 862

bbn1ws0wxnclaf8y8cfm9q4dhdkl8af8ts8vwerwfy

Wallet 863

bbn1ngh5vhmx0juwt5xywqpcc6a6g4ht9dg4nan34h

Wallet 864

bbn1r55e7l89q6ylr3ny8v0g2alm5wkdr0q23d9zaw

Wallet 865

bbn1jxdw8wzlr8ud853xhy9dnuhn6frn03w24naqqz

Wallet 866

bbn1mwjupes5ufj8kfmnyqqxv9artqrlauqpuzz63t

Wallet 867

bbn1fkylm3p4tlc4rrycywkyzy6apcpe9lf4aczecy

Wallet 868

bbn1xe35vwyq8esph87dw06wlu2mzmvau0lucl57hy

Wallet 869

bbn1mzcyxfxh6lg3mcapkxcypn7x0g9r9e96xz4mfj

Wallet 870

bbn1ae4sq0d8cnqf0zretm2wsl2qe9g2y7mggyn474

Wallet 871

bbn1l7mvqufy4987ygk948vwe73rdptgammnstjc6a

Wallet 872

bbn1my5mkv7qhtlldszpg633l2ghk54vcgu8mcpfrs

Wallet 873

bbn1k0n3m9mfheq638jmgfzfj4at24ygnvvxgdasz5

Wallet 874

bbn13xxue2ma2lleqftlwhj0lxcvsw0822n6ghnnxq

Wallet 875

bbn102qvx6na040t6r638saq7wha77xj4qt5vwf8xn

Wallet 876

bbn1m20wmdlscsyplz44s96kcy28rx05ufmn2lhca4

Wallet 877

bbn12uktdruemcdx0hajmwxtnluhy6jypqx6qzg84g

Wallet 878

bbn167yurdr7a8h92hr40fx36sqnm9jyqwjlulj9mz

Wallet 879

bbn12dk630455etk3vxuqnrwc8y2gfypl2a93d8hkv

Wallet 880

bbn1eptp70f6ct0z50aqndj5hkx7phkk8jlmk57vj9

Wallet 881

bbn13p2jzfguluvwk0y2yx9gpw4a3wj9cmeewh3q4g

Wallet 882

bbn1gxgtsragywhx0yh9vvehnldqjm72hmcmqz9qzc

Wallet 883

bbn1vwnl08qv4aqlkzpvu2d0cmglh8nu9tgjq6elgx

Wallet 884

bbn16lq8ugwr2dujruaqal6cqe5vwtvtlx2sd0yzsm

Wallet 885

bbn1kckuyq9g056lp05z9hcnf03z2gzx2rwvgez26j

Wallet 886

bbn13v5vefw76p8hj7jd4lqx34nnyhq896p99kkhta

Wallet 887

bbn1wzydm65clmpflgtql7trap50zcccghd5n6stkp

Wallet 888

bbn10evqtcnfqta8h8slthctu987rzmntyn2hecdgx

Wallet 889

bbn1py2f57sx60vuczlsekuaq06vpntlqy884lzxtg

Wallet 890

bbn1f4n7mcy2lxa5l4hx6ryt2svejeyk00yw4s7999

Wallet 891

bbn1hdg7g38dah3drennlk9e9qvkq7szrn3qampr3w

Wallet 892

bbn1qhecjv3thzcvykhyrqrkshyh6nf4psrwur4c69

Wallet 893

bbn1gss5mq39jq2kr2c7h3e7pa4tuuxfaaqgmds8ah

Wallet 894

bbn15em98nex3z99d05lsg545dw8x3m8sp3s0xh9ca

Wallet 895

bbn13y7fkwr0ryyffh00qc9px2qwymzcvhakrqdm5j

Wallet 896

bbn1zq5zqz0fkswedxcqxs5ach5v24tdkpzdqcy2pu

Wallet 897

bbn1s7ew6dw2p658xmu7x6a992vl3llg6g3yng7h76

Wallet 898

bbn189043vhd9ztuf4reqh3yrgqtax2m5ddtnkephx

Wallet 899

bbn1e3fmkhhmktwmc5jcrty3pmg2whzyllr0gftvzp

Wallet 900

bbn1zk5459wk3vahle9tjzre7zaxu8awyemlnk4ck8