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 701

bbn12rtfyc56n60ve3xsnw92v8rq4u66jvxcj3x0p3

Wallet 702

bbn1kqpw6tuaep5qfdstn9xfdgxjfhnlxgsn4uhl56

Wallet 703

bbn1r28ed7nwxtffvhn896fznj7eggdcmwk48ta3yk

Wallet 704

bbn1qh808jngqcx33r3fmvxs8fwcrc6jlggmz25xh8

Wallet 705

bbn15e75jr6e0d2yrpzw420p3zmk9el04a2ftyp88p

Wallet 706

bbn132zgv2ncmh8ccqhzdcu05lhglxyst3ym9yleh3

Wallet 707

bbn1f9qegv02nq9r5ag5sm0f2hfsk2yzprh4mm0pan

Wallet 708

bbn1aaslaq50jrh69mww3rrxzele0qygw3kyu82hqm

Wallet 709

bbn1q8kmxydmd648slgyp6qmduvgyet75pruud8y28

Wallet 710

bbn1qjcm0unqjsu0cgtw4vyglw5kc9cypurm7zf56h

Wallet 711

bbn168emttxnjw63g5m2gddvcs0zq57dp6d9xk48dv

Wallet 712

bbn16jptqfmkee8n88mxyq896q9w2dvmsq8uu83ls5

Wallet 713

bbn1h5kqk49qply5mzr9lh0er377k0rtxdpsa9kg75

Wallet 714

bbn15pvqg7esgvux6cpve54dspsk37gvu7te6ucpqu

Wallet 715

bbn1yn6mykfasffpgtkkgfeepnykt9jf8cqx54d8yd

Wallet 716

bbn1zvs8lzyq0lv775lvnjgkuvkqeuc7r93mvvqmcl

Wallet 717

bbn1r06r88pk7k26s4t4vj3g58lu8ex0zgh6e96x2c

Wallet 718

bbn1czv6qpwurywgtdnj387fnlkde4alsehx7d7tqg

Wallet 719

bbn1yrrugzy6f02vm5f9najz9p6ymat264xu2lwtl8

Wallet 720

bbn18pre0p6v3jcrpkj8u8tpw9r7tru37gz4stahcz

Wallet 721

bbn1he9t9zxm4qcrrrc672gfla0a2fpupsu97x57qz

Wallet 722

bbn1udw4032y7my0q9y0mp8ffry5m2u5xl3dxscc0y

Wallet 723

bbn167uwkpl6k4uz8t5fxettpqs7nw7nqu4guwxq8l

Wallet 724

bbn1ef073hrglyj6udet5w5w6vxdyc95qvnns33v4z

Wallet 725

bbn13aru23fepqs4xlu3lwvlx3zuzuuuv0pmm88q0z

Wallet 726

bbn1xa2jymy4zzj5ehk788k94f9vrue9pxy833465f

Wallet 727

bbn1zmanmvhly0dj537ugm99khhe9zkze6yvk0uydl

Wallet 728

bbn1drlqh5f5tmtzy53xa3k6ux58du0lclksh5yf4z

Wallet 729

bbn132vtsp6639jud5gza7szgvv7g2zk4528whznkd

Wallet 730

bbn1ml8hvcv73knd5nae65ge7ceehfy5yj5yt08u0q

Wallet 731

bbn19jd6dj8vmqlncj2ux37gfvrkukma8t7sm6e5qk

Wallet 732

bbn1u8gytxpr53a29tkhsty7lmuspphgcfehvltq72

Wallet 733

bbn19s33x90mn9v2hzm9nc35rdd94m8z9hx95en6v4

Wallet 734

bbn1qm0hhug8kszhcp9f3ryuecz5yw8s3e5vcdmff5

Wallet 735

bbn1p9hsz5wp80r5ncrgn3jvvp4w5a8ka66ef76h6d

Wallet 736

bbn1wnlftvamjdddhn6ftjjlz4xfyyfqjkf9vep29c

Wallet 737

bbn167q7gcrjjpcpr3av4wchkzx8nyj27980dp9k6w

Wallet 738

bbn1mkka0w05ad7gndgyqhdv7cdpyn956n9antacfe

Wallet 739

bbn125s7s07qwspecs296ytcgn4y5e3ht26pfae7rp

Wallet 740

bbn1xaxha6d8lyg5lfkm65hrmj5f79ck3qmx79xd4v

Wallet 741

bbn1wwwscvmqgl0ewua68p74agzdvc0trl6vagscur

Wallet 742

bbn1wvvffsxjqv834suly69c9rpcvhynlfx3qzzj4z

Wallet 743

bbn1zay6l9akluul7grn4jvpr8kxehhhmccqmnqt9s

Wallet 744

bbn1x8lvvq000kcu37stck2j77cjszhev07acjq6cl

Wallet 745

bbn1f2w6ywddk22fl07w7263wyw2zyc2haxktrakkq

Wallet 746

bbn1eh64xuz68nmtcrufsnwjk5a0fwxstuyhtmaze5

Wallet 747

bbn1sara3xelzqktnhshsxpajcvdpxjfamxca6wckf

Wallet 748

bbn1g9u9jx6dtqymx5dxzrqy2xc0jefc0mm0aykhrf

Wallet 749

bbn1r53kukgfegj69hn24dv6c52d7rx5sd8z9taz78

Wallet 750

bbn1p4mtvvp77r2y9qkdddphgru8je9jhm055vv6zf

Wallet 751

bbn18z49kq0x708sqp4ucnja8sxxrev975te3pqds8

Wallet 752

bbn13zj9d3p0j3edf40nasp4u5dvegrzd6d8f3zrjj

Wallet 753

bbn16fmwntvtsz0kgfx3805lxcmett20kupse5sffd

Wallet 754

bbn1nqyekssj08zrkpg49svfrgv4kgne3l54zqwuck

Wallet 755

bbn1cqvjtylesr2ucgmfttc9852a7ufz6w8jk9jvxf

Wallet 756

bbn1h82pruwrzaysg7q4a3nv6rakh0zn3mqjkafzav

Wallet 757

bbn1e57y24xp9a5hgedasjz20lz6zwwnvmxjagmhnc

Wallet 758

bbn14wpw0h60t5rj4yge5454ckd7xn7a3tk67vrg36

Wallet 759

bbn1kemcsj0v5mh4easqwq39367x08qslxypfq2cs0

Wallet 760

bbn1wcx4avqusvkny6plpvhdfcdz3eljjczh0a07qt

Wallet 761

bbn10kvd0h4lcpnqz0883hatqcwpelrdulmhvy7g03

Wallet 762

bbn1rmwnzsvda5k33nup3qc8d9g7qu746zwune6gz3

Wallet 763

bbn1dpdgc48lags398l00pxje8mutlmrsn9papf28g

Wallet 764

bbn10ag4am7a3plfr29xzn93fpdzq3r7z7exqla29f

Wallet 765

bbn1v6ynfp76wjrx640zr6q2h4fqvf7gwwu5xny303

Wallet 766

bbn1lwu4hd4fz0lqgtzlpx7wl52qys3cxmnsdeuddm

Wallet 767

bbn1lu27xjnmvjukg87a2p4d3dxg5epdlrtwsfsavw

Wallet 768

bbn1nl23wmq3fnq3883q9lztcpghqp9etyxwfvhvx9

Wallet 769

bbn170wtj76cqucwsmaggt58g99402xspag0gvnxhj

Wallet 770

bbn12t976e4zns2gvr0cwf76yc2sndmqs7wxjntujs

Wallet 771

bbn1mu2k5u6kul2vfzre2mc3uf28daufvxlgmmjdsk

Wallet 772

bbn1ptkcnuyr2qv3zt6hnyuqh02luzazn5t5d4rhnu

Wallet 773

bbn10ujw8lp4pku7rdv4hl4g3tg8tc7erxcqu25npr

Wallet 774

bbn1yaw48zxvu6wp787qtj99utara3x0735ffjx7xm

Wallet 775

bbn1s3tztk84njann3vz58t7hnfsmn6jwyuns8qwfl

Wallet 776

bbn16j0lqzqmf4fu8aveuemfsqn7tzg0sjjp5yyx7y

Wallet 777

bbn1rf9pza0kufp29v7srcmtrjr5vuhdxpl9jfx8ed

Wallet 778

bbn1c3l2vkvfsqsgjnd6lr6xqp4264upgz05ppjncj

Wallet 779

bbn1v24s2f70h0qnfy0v86jehhy9cwr08uttstsysl

Wallet 780

bbn1685j5hlj7454s8d6srx7qmzaml2w9zcxaw7rhr

Wallet 781

bbn1h3qew0cl5ewtks88txu7zf9ufc4srpjcgqfqkx

Wallet 782

bbn1wj69qsa63436waqrmd64r4cujgz9hcknfpy7vt

Wallet 783

bbn1efd34lp4t7un2uk3d4y26gdygml5gg6kl4yx54

Wallet 784

bbn15257xcn83gnxxn64earjfq5d0yw57jxtqqv205

Wallet 785

bbn1u4tzganpsvwa46wxqq2lhduaap3y3qu8c8dg5z

Wallet 786

bbn18789g874r45p5rxugeh8szc7xgf9rd9w5rmmvl

Wallet 787

bbn1l2jau4y3rpnnm5tjd7x5lz28vn28g502zflc0g

Wallet 788

bbn1secvq8ulcj38es3mllukdajwfpyrr36t93zrcu

Wallet 789

bbn1v6xmrhsm50669v370emvwvlddjexs4pl4jzcw9

Wallet 790

bbn1hzk644v07ec9t6348lsvgtmmrqeaaec658cyzh

Wallet 791

bbn1qlp889utpx2dzyzj7m0e7wmfd8s3huf8hura7z

Wallet 792

bbn1yqhth9glc9clvyzzgjtx4k4ruytrqf47dfn6kq

Wallet 793

bbn1ed0leutsrr0tt6y7jf4aqnr6gsmwm53p9elynm

Wallet 794

bbn14eff9e7hp9l6y29up93dhacswer9n4fyu5u2tf

Wallet 795

bbn1r7t03nzgfg93qvachnngsk6wyuctyeu92hh822

Wallet 796

bbn1raq2sg9w2877skj7adfyvnvuqdwuqkzf6mc35c

Wallet 797

bbn1jnqv9kmwsndetcae6crxsgvpf3u9st94vjcyad

Wallet 798

bbn1t9ajjts95ygs276299gumfw8qt775f2ut6qphg

Wallet 799

bbn1e4h9sfafrqj72l4l90p5j7gfujkuw8zwykttyw

Wallet 800

bbn1wgc7hrthkpt6gydv5t59kryjjtdtlnyw6mj37l