Link a Polygon Address 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 Polygon address and BABY address. Note that only Polygon addresses that are holding the Bitcoin staking Pioneer Pass NFT are eligible for the airdrop boost.

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

The JSON format of the PoP for NFT claimers looks like as follows:

{
  "babyAddress": "bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh",
  "polygonAddress": "0xa2e83b3d772901ed37d08bbe0f2e78e28e964679",
  "polygonSignBaby": "0x039ef5d42a426e91766de943a67a377c07fd6392a3c94b6d31a7425d2a1a159215e5aa748460e292f8b1c56dcdb5e58b4b19371fabc0542c86c296df96d51b601b",
  "babySignPolygon": "VvjnZkZc/n45vp5ahVhjEvQN2pYFH1tlj2MLAhin33U7NVKX6T5iHSS+Qoh7nBaxpykJZ33u4G5z4A9pfiPtYw==",
  "babyPublicKey": "AuFdQiPcFg40hsz7RUMLFvScNlKVmz01g/yt982y75mJ"
}

Detailed specification of each field:

  • babyAddress: The Bech-32 encoded BABY address.
  • polygonAddress: The hex encoded Polygon address that holds the Pioneer Pass NFT(s).
  • polygonSignBaby: The Polygon signature compatible with the personal_sign format: personal Namespace | go-ethereum. The signature must be made over the babyAddress (i.e., sign the address string you specified above for the Babylon address) and be hex encoded.
  • babySignPolygon: The Base64 encoded ADR36 signature made by the BABY key over polygonAddress (i.e., sign the address string you specified above for the Polygon address).
  • babyPublicKey: The Base64 encoded BABY public key, corresponding to the babyAddress.

Note: the BABY address and Polygon address association must be unique in the airdrop claim.

1. Generate PoP

1.1. Setup the Staker CLI program

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 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.2. Create ADR36 signature over Polygon address

First, we partially fill the PoP by creating babySignPolygon, which is an ADR36 signature signed by the BABY key over the Polygon address:

stakercli pop sc --baby-address bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh \
  --keyring-dir /path/to/keyring --keyring-backend file \
  --msg '0xa2e83b3d772901ed37d08bbe0f2e78e28e964679'
  • --baby-address is the Bech-32 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.
  • --msg is the hex encoded Polygon address which owns the NFT.

This command will produce json output like the follows:

{
    "babyAddress": "bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh",
    "babySignature": "VvjnZkZc/n45vp5ahVhjEvQN2pYFH1tlj2MLAhin33U7NVKX6T5iHSS+Qoh7nBaxpykJZ33u4G5z4A9pfiPtYw==",
    "babyPublicKey": "AuFdQiPcFg40hsz7RUMLFvScNlKVmz01g/yt982y75mJ"
}

where:

  • babyAddress is the Bech-32 encoded BABY address.
  • babySignature is the Base64 encoded ADR36 signature made by the BABY key.
  • babyPublicKey is the Base64 encoded BABY public key corresponding to the babyAddress.

Note that thebabySignature corresponds to the field of babySignPolygon in the PoP data structure.

1.3 Create the Polygon signature over the BABY address

Next, we fill the remaining parts of the PoP by creating polySignBaby, which is a signature signed by the Polygon key over the BABY address.

There are two ways to generate the signature for a given Polygon address depending on how the NFT was claimed:

Browser web wallet

If the NFT was claimed through browser web wallet, you need to go to the web application which enables signing arbitrary data following EIP-191.

Note that MyEtherWallet is not using personal_sign method in Metamask. Therefore, cannot be used to generate polySignBaby. An alternative is to use this web app instead. Source & a demo here.

Local keystore

If the NFT was claimed through local keystore, e.g., geth keystore, you need to use a personal name space (personal Namespace | go-ethereum) and the personal_sign method to create a signature as follows:

curl --data '{"id": 3, "jsonrpc": "2.0", "method": "account_signData", "params": ["data/plain", "0xa2e83b3d772901ed37d08bbe0f2e78e28e964679","bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh"]}' -X POST localhost:8550

where:

  • the first parameter (starting with 0x) is the Polygon address that is doing the signing, and
  • the second parameter is the data to be signed, which in this case is the BABY address.

This step should produce a tuple:

{
  "polygonAddress": "0xa2e83b3d772901ed37d08bbe0f2e78e28e964679",
  "polygonSignBaby": "0x039ef5d42a426e91766de943a67a377c07fd6392a3c94b6d31a7425d2a1a159215e5aa748460e292f8b1c56dcdb5e58b4b19371fabc0542c86c296df96d51b601b",
}

2. Submit PoP via API

To register the PoP, you need to construct the PoP payload with all the data generated from Step 1 and send it to the API endpoint as follows:

curl -X POST 'https://airdrop-api.babylon.foundation/pop/baby-polygon' \
-H 'Content-Type: application/json' \
-d '{
  "babyAddress": "bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh",
  "polygonAddress": "0xa2e83b3d772901ed37d08bbe0f2e78e28e964679",
  "polygonSignBaby": "0x039ef5d42a426e91766de943a67a377c07fd6392a3c94b6d31a7425d2a1a159215e5aa748460e292f8b1c56dcdb5e58b4b19371fabc0542c86c296df96d51b601b",
  "babySignPolygon": "VvjnZkZc/n45vp5ahVhjEvQN2pYFH1tlj2MLAhin33U7NVKX6T5iHSS+Qoh7nBaxpykJZ33u4G5z4A9pfiPtYw==",
  "babyPublicKey": "AuFdQiPcFg40hsz7RUMLFvScNlKVmz01g/yt982y75mJ"
}'

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

{"message": "ok"}

If your Polygon address does not hold a Pioneer Pass NFT, the API will return a 400 status code and the following response:

{"message":"No Pioneer Pass NFT holdings","code":400}

To make sure your polygon address was successfully registered, you can query it by the associated baby address.

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

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

[
  {
    "babyAddress": "bbn1kg3hw2trn4lpv4kg92tafqpwq4lpea2ep5d9r4",
    "polygonAddress": "0x74b9b4ee0caaeea82c6b35385dc9f7c7d57fd9f3",
    "babyPublicKey": {
      "type": "tendermint/PubKeySecp256k1",
      "value": "A7pgdC3q+IOeeavUqdhYpupU2U/qL+kEu0wDxXLhFs6m"
    }
  }
]

3. Deleting the Proof of Possession

If you wish to change the BABY address associated with the Polygon address holding the NFT, you can delete the already registered PoP and then register a new one with a different BABY address.

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'

where your-baby-address is the Babylon for which you already registered PoP.

Example response:

{"message":"Welcome to Babylon Airdrop!\\r\\nAddress: bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh\\r\\nNonce: 0f7c99f145"}

3.2. Sign the response message

To prove the ownership of the BABY 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 sc command (recall the need to install this program in Section 1.1.):

stakercli pop sc --baby-address bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh \\
  --keyring-dir /path/to/keyring --keyring-backend file \\
  --msg 'Welcome to Babylon Airdrop!\\r\\nAddress: bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh\\r\\nNonce: 0f7c99f145'

where --msg is the message received from Step 3.1. It is important that string is closed in single quotes.

This command will generate the following data over the provided message:

{
    "babyAddress": "bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh",
    "babySignature": "zuuNchJnEz31HZyBX+kftsBSuQJJnrjA2vBQTmOctVZAjaNNvVpTrItRBSxmUJKHN+E+4POyjnxTrfBXhgV9MA==",
    "babyPublicKey": "AtU4i0OjGcvtdeiJjygOaHmxk9JvNKZVipu46I6zLi/z"
}

Now create the payload and send a DELETE request to the API:

curl -X DELETE 'https://airdrop-api.babylon.foundation/pop/baby-polygon' \
-H 'Content-Type: application/json' \
-d '{
  "babyAddress": "bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh",
  "babySignature": "kS5WelO48HFhNdhdVDQ4cNMDgiANzpk4aWtwqGCAr7kdo97yNQdcMg/dbT4ZmJmhi57U0LdXcBahTOZf0dTO5g==",
  "babyPublicKey": "AkFPu2WhXw59YxaZjB546+FLGY/4K/IWKnUqa0fGgXd4",
  "polygonAddress": "0xa2e83b3d772901ed37d08bbe0f2e78e28e964679"
}'

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

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-polygon?babyAddress=bbn1uxx48k7lzrjsy8t6l34m76jzzgjee2m35ppfhh'
[]

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