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 601

bbn13ahym75tvwurlhs38sthp2sra2qm8wnupmfjj5

Wallet 602

bbn1c8w93r0rwxlxmyllaplxfru7526q0q3tnsdfu3

Wallet 603

bbn1zylcgg75hyp0s5eqshv97avjgc52jerj2uy6zu

Wallet 604

bbn12klnxy7zdg9wnlnf6m8w486k57rt7cnr6ecdxw

Wallet 605

bbn1kafvgw99r3nprqwyqy7mwpdusn7jlju8tps870

Wallet 606

bbn1qpmk9fydredjaxdqjtawktzfch6zhs9dqs8g32

Wallet 607

bbn1ahrf0u0xz62jnz4qfkglcphfsy9fe4hygvdr6y

Wallet 608

bbn18peltfpx8kcfa3fkwf35k4ywa822h3pjkaxhk4

Wallet 609

bbn1jrdfndqk6xzl6jr8w6sxr7wdk4g8vyrvh2ztrg

Wallet 610

bbn16h8lzjs5y4j7v6lm6mq7qglh3dx6285rgrz7ul

Wallet 611

bbn1a4s07re70ewdwcuvzlfgesa9em97cd6ugu4x5t

Wallet 612

bbn1t9ka4w0hyfn3kuraykpgcxtnp9xx5z7a0leaz2

Wallet 613

bbn1wrw94xcfgqe03fs27j284lu2f9l0a7w2u8chvn

Wallet 614

bbn13wpfmuj08aqer8rqu5dyakxhyl8d8ky2m28mmr

Wallet 615

bbn1n0hlpctc6cm23myn8aswg9dmprn5958srulg6x

Wallet 616

bbn195d9rs092ae5fcvhft36qmpnl96kj4f2p4pw2e

Wallet 617

bbn1jmwfy7d4gps993c7gl0rh8a3jnpeedrxduatka

Wallet 618

bbn19f2t544jca79lclnnhsvspmeexpk2vp2xg2guu

Wallet 619

bbn1wvrj0ucwlz3xukjuhq53pcrx5zekk2rghlyqgz

Wallet 620

bbn1fyqpmtu4d6zvlzmp396y9cq3zxauzmgr28rlgx

Wallet 621

bbn1tkjhpkh9n0szsw752jdq3z4up78g84guz8gdx5

Wallet 622

bbn1zatnhynr6l5ufkjja2gaqvel9kg6uuhqw8wqjc

Wallet 623

bbn1mznsvpmv08u0tvjfczh0yphrtc2nnjx5ycz5je

Wallet 624

bbn1a25wlvzylmypvdqdutjg7533sp069lajrxrmlz

Wallet 625

bbn18s87426xmrpwtw4ethtkd8qmrgauy7xkruwhjl

Wallet 626

bbn1a3xp2s272gmzu2lgelqswc6c9y9ee35xqs7ky8

Wallet 627

bbn1ea52rr7w6j4wnekhkuusfvruclc3au4skqq4kc

Wallet 628

bbn1p8wwfyfqt63p5gl9hssgr8fhjnn2m53vxn2pdj

Wallet 629

bbn1xpkxjuket26fa7xlklrj4qaj0fse5u9a7lt27t

Wallet 630

bbn1j3j45wjj9ktkapj0tgftp60wmgy0ssrtg4345d

Wallet 631

bbn1y3u06hdgxa7avduse89y9nuqusfw8zr0d0a0lj

Wallet 632

bbn1v6npe3zq4fhglkxujwsma7889jhw930gnzyjnt

Wallet 633

bbn1hm4h9k8fqdnu5wvj4qfleztqpmlazfza2mkrq7

Wallet 634

bbn186ka9nud4p5aa0aafenvenhmceyd4arxcc0432

Wallet 635

bbn1defqvnv79sxyea2s7s7cawcvl6tx4phrh0wyqe

Wallet 636

bbn1gnj373hwe6wmkj6gv507h07vwfkv57gplkgmmy

Wallet 637

bbn1d2rm4hnxp26vfu8un6zmzqylf378nmucanragn

Wallet 638

bbn1uqucck4xpdmtumv04yq9c6vq3h8dv3nwsc9hq3

Wallet 639

bbn1qn3dtmk2q2uy6n2hpvs38df6y7s8zj9d7a7f63

Wallet 640

bbn1e4vxc30tjmm4kymlg760sz6mtly4vkdmvr9sy7

Wallet 641

bbn1xkpka8vfppn9qkps49p9jskluqlm7kwf28zyuq

Wallet 642

bbn1aaw4gkwnwa5ccep2ftfs30dvuu7quejem59l2w

Wallet 643

bbn16ky6lyplgfn0f42fks2n96l5fw2xakmuz77jqh

Wallet 644

bbn1znx98thp8ngah2y0wx8xayz8uzpeukum0pgv2r

Wallet 645

bbn1j3kvs6t2ndhxdc20ua67j0gesj22zw7hhra9hl

Wallet 646

bbn17x3um5kztavsgnd2agcajy3ncg0zx6grsszyq9

Wallet 647

bbn18yu73r5vjcmlsgslnfxtaf9jlh7s6v2ad8aa2g

Wallet 648

bbn1muqj7tz03d8w8th6esmrj0qshh23u88uz23ma6

Wallet 649

bbn1q3x5vuw0c57kqh77p8q4gmya3t8ruzk560qs9w

Wallet 650

bbn1dgywx6x8xa54f4llrrn7a54mhsxrk79jn6tj2h

Wallet 651

bbn1tes7chee9sxn6y35v3yka7dwhw60w8756gxzf3

Wallet 652

bbn13xl6rjuvxy0900anfce99u0xc77uylw3s0cdv4

Wallet 653

bbn1tz44xy6dzrthzc6kn643newy9afg0jtcyd4h80

Wallet 654

bbn16flgm5ccllrf239y5qlwcj4uesv3sxmcl7hkz4

Wallet 655

bbn1kyyn8yh0rgwg2etpw3kggqgw6nuutl53v6rlq9

Wallet 656

bbn1ueqtgfmt6927pmdlhgrpx4httddl0j6hmkx2e6

Wallet 657

bbn1zfjcq6m5j0ka3lpp92zq4vylrpfx70w8hx6jsc

Wallet 658

bbn1lnc5d68nnxw940ky03f9hlav0m5wemhk75afly

Wallet 659

bbn12sfpwdl9g9r62zxpmn2249057zsuzd5nqj20q6

Wallet 660

bbn1fa2j0hpnm4al2tyjhzm0jlq3ryakmszshndsmn

Wallet 661

bbn17d9ndz84jlsjwcz72fs0aamqtn04vst3rlm09p

Wallet 662

bbn13ufsmmg6heh9dl4l3yukqf5m5hs5t8kywzj2k9

Wallet 663

bbn1a4xy6qm2yw90qsk86t0yhn6waeethq59x7wp9x

Wallet 664

bbn1xndutvupw73sl0akvwkr7vzkann3cweencanyu

Wallet 665

bbn1t0hjalckkj4wthak50snh5av2xytqtcwr443ul

Wallet 666

bbn13ud7zjkxqlqggkrzdz8d6ywhgxrcfnge96gtg2

Wallet 667

bbn13y4m0e6zdd5khpexdu06e03tlpv20ja5jyx6g5

Wallet 668

bbn1epmjmkhf876wpqc3yt2slzs8p3wapm8krx65xa

Wallet 669

bbn10pgllaa9d27kpl22zgma3jhtdtll7je0ynsuhl

Wallet 670

bbn1fqsfh795c3cvvhkd6nd2036mzavrnchn0a8tek

Wallet 671

bbn1cxe93dn0a09pfl7euglq94grl57g8pd2kjx5zr

Wallet 672

bbn1x55msm9ae935gh246smyw70yjzceqk36evjg2r

Wallet 673

bbn1agudvplxutven0mhq9wcheg93hr9c3l0h8n34c

Wallet 674

bbn12wvy5aeg8hz6lfceqe7g9ftc7vxlkgexwztkwt

Wallet 675

bbn1sx653gxfcrxtjgwemg3stu9lzuajxfmt6rr35f

Wallet 676

bbn19yu623pj6ekmhwjslc0a7akwv8jtj80a2v0rrm

Wallet 677

bbn16t8jr82cek4w9vzwgklzqm58jglzqsgwyj92tj

Wallet 678

bbn1lhjy057hpvumsfskrv5c7vdlr8v5qnqjfsnndh

Wallet 679

bbn1j38p25art0w2lk5rmck9t3tmndfk39m8709jza

Wallet 680

bbn14ktyza6fnhvlwwwq0ru2lerw98ywj40zvnecd2

Wallet 681

bbn15rgnplpz38zrefppap3v5494p27qv9kn4tssqa

Wallet 682

bbn1ulvy7jpwcrxzf3lf5y0gc05jevj6prpyvc5y8j

Wallet 683

bbn1je9ee2tl4jmt6ck7qx9hstttp3wyvu0vz5fwzk

Wallet 684

bbn1tsg467x6ky8u535jm6ee046lthsuzuk3uxfwgr

Wallet 685

bbn1rxtqng5e0h8tv36fl46gpurgvq74tte6j5aapc

Wallet 686

bbn1h5h2m42jzkyaaq97gvcr62ms3ra7r6pjqmsla7

Wallet 687

bbn1xde2msm5jxf6znv0mrqc9lcllsdjnruvhyqwwf

Wallet 688

bbn1r2qt9f4eva48nt3vufx6m75k9x388mpsr9kefu

Wallet 689

bbn12u9v33r77wdt339md5zp0qrmfnckkrnp5pythv

Wallet 690

bbn1mahdlgkhysp5vhq2d62edl7206l224q6sfcmfe

Wallet 691

bbn1yex782zqgpqhtvztw3dz8yeagvf6yue0pquzw6

Wallet 692

bbn1ayk58fzn5k23evztd3p38du0a0jhqf2uh7k0k3

Wallet 693

bbn1yu3nttuzdz3jryekc9tz3qnx6l5754r8fvcdd0

Wallet 694

bbn1x8qfla6d4sp6fx4pdsqmguytwf274tu3vsn2q2

Wallet 695

bbn1xwazl8ftks4gn00y5x3c47auquc62ssuj4htef

Wallet 696

bbn1z8evpkjz6ycq8dcasvssuyxdcmh0dzpphq7psw

Wallet 697

bbn166u333ljfnlhc3tghm67qsa8he8jxxehqq0drn

Wallet 698

bbn1eaftkyc6k7ux3ty0pxr5qsmgq9fdnkye9qghn4

Wallet 699

bbn1a9dn4wyvdrlg9jsq0ls5j5jc688cpsr4zzc7kt

Wallet 700

bbn1z3e7r6a5kt4a35mvsd3r2cmdtwtfl00wrkp8ds