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 901

bbn1pkxuhgsxdz2mvuxc3vxh8unl7tgcs3lclpx57h

Wallet 902

bbn1r60ewefncg88xtv7vnw5l4tk4a2hyv74tr3lkh

Wallet 903

bbn1nu30l6zxe8zmzrs3cp9kmnqajca6nlym7sfwa5

Wallet 904

bbn1mszyafkle9ekseun357f52czshcklfp099lqn9

Wallet 905

bbn160yfcnjc3ggy2jgrxdrfl87atzz77h97dcwvm9

Wallet 906

bbn1zmrxrrwkqs33lsq8ec8t8djq8w8lqwuuaxpwxj

Wallet 907

bbn1spdl4n59pgmkxlrp6w3xm55xsadyzlgv0yump5

Wallet 908

bbn16fgqu3h05lwumhep63gr9lz4hqgum2xml07guj

Wallet 909

bbn1c7zacxyggfkpw0jywrpme8uwfllgv3vcvxd4z0

Wallet 910

bbn1nw43yuz38e4dc8q2n62plnpxmnfzlugpvmhfh0

Wallet 911

bbn1dk5zgngqudvrfgrswswfsfftfspzdkrm9uypj5

Wallet 912

bbn1c5h56fqq4ht8x922gwuuxv5pjfajzp4ugukm8c

Wallet 913

bbn1jl2843s5uat5zmm270wkzexlkvzzwms0c0rs95

Wallet 914

bbn10prx3q0xtlagxgx6ztf0vdsg23n3czasexykys

Wallet 915

bbn1pkhqdvdm6ydf80p24vwv8mm2g7wk5uq9w0t2az

Wallet 916

bbn134tq7rc3e279m7ny3l2tmw7aa2hnyr3uxrmnl3

Wallet 917

bbn15a26lza2l88yzer6hald98flpcg870hvecpk3v

Wallet 918

bbn15ywemn9lr7gu7mpta59z3lnkejcjtz4aj88qrm

Wallet 919

bbn1c9w76va4fdnn5jp87l87gsyguzwummwcnp7r3s

Wallet 920

bbn1svrxldd2pyhsdc8jnxkghmyc7umvm24032wlad

Wallet 921

bbn1t79l9nnwspu64pav9s7rvwdd6y5skguuna8v4t

Wallet 922

bbn1fz2hy2th0pumfmufswlt2nl2zg390c6ux2pcf2

Wallet 923

bbn16z89q6re5u0t2dv6aqqpuu5ypd8uta6zmccjaq

Wallet 924

bbn12c54wl35pyrrrzumekrtm9qwrfdkapl9vyn60s

Wallet 925

bbn1expmg8p0h40nwzy2pwwrjgxysv0n9f7dtju6sh

Wallet 926

bbn1pva6d5s8lp5vpr7kw92067ul5jm688wkkr02ag

Wallet 927

bbn1th5r9ln0w7mcfcf4dst20qq3spyqqame5adf9l

Wallet 928

bbn1jfjxnja94hg5j02jjaxwrak5ap50t20lym4c0y

Wallet 929

bbn1q8q4k4y7n5mmah3ymze4jcgv52uk2lhxtldn00

Wallet 930

bbn1ewym7rl86fsjch2ggkvkya92mrwct63fqggpuc

Wallet 931

bbn1dj3mn8dvrzza5gnscdt80nqfhzsf9gpqzp30mn

Wallet 932

bbn19ds34sj8w2k9e3f8qaazmp0nl07972lpeltraf

Wallet 933

bbn1epuw7kpqzlpp5ps8zaaf30ljj5j82kjcc92y00

Wallet 934

bbn1nmlunpp7cps42kn6gfnz4gh0v3sj90w9437mn7

Wallet 935

bbn1spjh3cgnr9v3uukpqqx7spsw8smgh63j68sknp

Wallet 936

bbn18gmd57qr5yzjrj984mtcv25t852h42jz7kw3q2

Wallet 937

bbn1zmhhxfrhp4f62arp85n7v4x5g4xl8xsljdu3fw

Wallet 938

bbn1q3ts5qhrh3m6t970egemuuwywhlhpnmm54c86h

Wallet 939

bbn1s6x0vfk8kk26fzhlg6vranurnm402337hz3p6p

Wallet 940

bbn179x9gqd47g7j5750qmcwp6xj5pyk6vn7s64kvj

Wallet 941

bbn1pm0eajmrzckyn5fjtsck9x0vnpsxh8hx2am65g

Wallet 942

bbn1u40kfxn7g4utge4fwyqyhx7wuv9qndsq9xu2sc

Wallet 943

bbn1zelxsqz6gknelf5rxr0fwr8wsdnlukth47vxwd

Wallet 944

bbn144dvkfv4c9kjjucqttwq59ruzf4s4fpd8clhwf

Wallet 945

bbn1hnvtetslaykn2zc5yhs3pt7wzzt60em8vl2fs6

Wallet 946

bbn1006rlnsuqwpc94dzdnw6wxw5gcgcrpuye24ekg

Wallet 947

bbn16lk4ksyjtxznvje4k6cyv4reqsytpjwk96escj

Wallet 948

bbn1xwzwpse4mqenxtxexwhqpjdg598x33h0fxs9g9

Wallet 949

bbn188prj9f6vuuz6xx8dw2fhr35lzsh4exfqahg3e

Wallet 950

bbn1f0zfr5u3eapvrecrxryncec957zwj4lsmdx3eh

Wallet 951

bbn1jtlga7438cnw63hww9rx33euu522rj3rxnlyf2

Wallet 952

bbn1fsmyemyh8adcw8wnctksqjldq3pc2557syf4u0

Wallet 953

bbn1f98my05l2yzyj5hjvvkjqrdv64wfdzzgh936ae

Wallet 954

bbn1v0n0vkx28yqx8ntflx2kwc94ul6cck7a4ne6kt

Wallet 955

bbn10srw59hax4dxdkrq2h3hnyg23kp0ygh9h5fxfl

Wallet 956

bbn1pywwcuutxedsmtxthcg0vqa79jvu8ex44548nq

Wallet 957

bbn1fte9nqmzzyfjhrd9revemy650uxslg2mkux4uk

Wallet 958

bbn13lhuld4kag7f3qcfumevuxm6w486a9vd22x5fz

Wallet 959

bbn12vafsxgwe8l5waz3g7vgpphjuzecelmvemcqn2

Wallet 960

bbn12zz7zdpkp8rsv5tv8rs2nx4kltattryz09tmc8

Wallet 961

bbn1s4sxp8lzpa5gh87su20ffsy7dhen3dcuu8x6m4

Wallet 962

bbn1gnq9r7jdq7fpdj8nsgx6utq07lqh6tvevtwapw

Wallet 963

bbn1d30wj2qn56wnmhfaunu586qpergh7d32z4muah

Wallet 964

bbn1ygdn4zyg9vxdg4c6j4xkrpjp7xq5d47dyeu5v8

Wallet 965

bbn1j3usscuamx2clqcdagdccxrrvk3gqyljnch27v

Wallet 966

bbn10p02d78247t3x6fxusrz0lgw459ghcqf72eqla

Wallet 967

bbn1rg4m7lnsqdv5fhkpqhyszxyxqvrmf857eq0kpj

Wallet 968

bbn1hvlnzs3zqy6s65st089uamgqed5evvaap9pvxs

Wallet 969

bbn1uv66rurr8ny8hjznkay50kxcj83fnedxawmzu5

Wallet 970

bbn1mafeeemfgrdhl6plsafdu7vvdkzgnngf8ty5c8

Wallet 971

bbn1kufhqv8yda93ksx9zrhmeq7pyyekr2qn346x6l

Wallet 972

bbn1wkzmtrwc8w4w0vwk74qvkl5nvgfg0gc6ryfs8k

Wallet 973

bbn12nhn0hp7966tt6s6a66nr6ss4m83ytdc22kc8r

Wallet 974

bbn1fh629gkc7qq094jjwa8kd7tt27svllmv6zu3nh

Wallet 975

bbn16xhnjjjgjreut9g0tke6nth6cwm749cs8cng0h

Wallet 976

bbn1fdssakacpgxnl3f6r3d3d0z88mrwceedzlhdg9

Wallet 977

bbn107aj5308rtp9eqvfqup2y586acgggwhtcj6fac

Wallet 978

bbn1ghkj63dxzk0h3w907neelajqg0n4c8svyww8lu

Wallet 979

bbn1uqgp6amz7yp4lfgnsmcsdc5l9jnjt4jwjg684p

Wallet 980

bbn1zsplxyyyquvvval3xsrvl2qx4cxuq2klslpqal

Wallet 981

bbn1msukz86gq5lm082lv7vhv3jeq2zsp9dg0ywv95

Wallet 982

bbn1f4mqs2qaem05etujjfzjm6w20ysgdgmpv0qhku

Wallet 983

bbn16kcqu6xquyzu8rvxpuv6dyj50e9wcw6gvh4xfy

Wallet 984

bbn1f5md67us6gydxezwc497rdauegynfqhgk3dzc7

Wallet 985

bbn16p2um65jmll0z7y724jhqwrr3p690lafsaktp8

Wallet 986

bbn12hja0q63ne6aadk32qxtar03z5jleevsedmz48

Wallet 987

bbn1h3ce5w94hfzthq4fy9wfdzh7ww5vq6tlyx7qek

Wallet 988

bbn1gc25466tu32kq6lgh9qdkcv0zffwes6nexsjlw

Wallet 989

bbn1rpcw66kncgx3rg0y5zd70yyrt9j97eqsc86de6

Wallet 990

bbn1v2vptyppt7cms4wgcggvrag23e9qfmpwkxmrev

Wallet 991

bbn1wgz0f8qkz6tf2f0l693c7v42dxxyquf6ljpkxc

Wallet 992

bbn1tqklrhmt4s8q477cjmnnfuerdkdm56wzvgs90g

Wallet 993

bbn1ckxkd0awj005mu3x8wv5u08ehsh5cycxaq809k

Wallet 994

bbn1pjs90ngcgfcha58nrvydgdjmw8q0s3eht0c82t

Wallet 995

bbn13u4thxrnku2z9cu7pvqc3dtdz0nyzqy32qnrx2

Wallet 996

bbn19jm4rgxfjkq032fznap3j7lh9ewpzgrzpzs84s

Wallet 997

bbn1uucp0cpnnw42pwngyu4wru9p38kc9tjh3ngnhm

Wallet 998

bbn1e8krh72furzxsq6uxq4ur8pdz0ecetr3za9wwu

Wallet 999

bbn1a8me2xyy5rfxe837csan5gndk30ul4gxmh98xz

Wallet 1000

bbn1fm2ga6gady36waglerryv5qfl0vdgpvre853e3