curl

Learn how to use Bitcoin JSON-RPC with Curl to interact with your Bitcoin node. Get uptime, blockchain info, manage wallets, and more.

Bitcoin JSON RPC Usage

Understanding JSON RPC for Bitcoin

This guide demonstrates how to use JSON-RPC with curl to interact with your Bitcoin node on the testnet chain. JSON-RPC is a powerful tool for querying and managing your Bitcoin node, allowing you to retrieve blockchain information, manage wallets, and send transactions.

Pre-Checks

If you installed the node with this script, your config would be in /etc/bitcoin/bitcoin.conf. Retrieve your username and password using:

cat /etc/bitcoin/bitcoin.conf | grep -E '(rpcuser|rpcpassword)'
# rpcuser=rpcuser
# rpcpassword=9a4e9cfac082721e870575a7c66178c0421512032a6d62af

Set temporary environment variables for this guide:

export rpcuser=rpcuser
export rpcpass=9a4e9cfac082721e870575a7c66178c0421512032a6d62af

For other guides see: - x

Checking Node Uptime

To check the uptime of your Bitcoin node in seconds:

$ curl -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "uptime", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/
{"result":60501,"error":null,"id":"curl"}

Retrieving RPC Info

The rpcinfo RPC returns runtime details of the RPC server, including active commands and their running time.

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getrpcinfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python -m json.tool
{
    "error": null,
    "id": "curl",
    "result": {
        "active_commands": [
            {
                "duration": 133,
                "method": "getrpcinfo"
            }
        ],
        "logpath": "/home/bitcoin/.bitcoin/testnet3/debug.log"
    }
}

Getting Blockchain Info

  • getblockchaininfo

The getblockchaininfo RPC provides information about the current state of the block chain.

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getblockchaininfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python -m json.tool
{
    "error": null,
    "id": "curl",
    "result": {
        "automatic_pruning": true,
        "bestblockhash": "000000000000003b5744e67b7f2a30634b98077055a58ff6b2eb1c160eb44a9e",
        "blocks": 1383644,
        "chain": "test",
        "chainwork": "000000000000000000000000000000000000000000000096db9d07fd29e70db2",
        "difficulty": 48174374.44122773,
        "headers": 2006191,
        "initialblockdownload": true,
        "mediantime": 1534268709,
        "prune_target_size": 1048576000,
        "pruned": true,
        "pruneheight": 1382612,
        "size_on_disk": 911147899,
        "softforks": {
            "bip34": {
                "active": true,
                "height": 21111,
                "type": "buried"
            },
            "bip65": {
                "active": true,
                "height": 581885,
                "type": "buried"
            },
            "bip66": {
                "active": true,
                "height": 330776,
                "type": "buried"
            },
            "csv": {
                "active": true,
                "height": 770112,
                "type": "buried"
            },
            "segwit": {
                "active": true,
                "height": 834624,
                "type": "buried"
            },
            "taproot": {
                "active": false,
                "bip9": {
                    "min_activation_height": 0,
                    "since": 0,
                    "start_time": 1619222400,
                    "status": "defined",
                    "timeout": 1628640000
                },
                "type": "bip9"
            }
        },
        "verificationprogress": 0.508263107545056,
        "warnings": ""
    }
}

Getting Block Count

  • getblockcount

To get the number of blocks in the longest block chain:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getblockcount", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python3 -m json.tool
{
    "result": 2391641,
    "error": null,
    "id": "curl"
}

Getting Block Hash

  • getblockhash

Return the hash of block in best-block-chain at (index x):

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getblockhash", "params": [2391641]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python3 -m json.tool
{
    "result": "eaaf8d4d27c5ce9b282e9ff870793382e14345436fac74ea40907320e50603db",
    "error": null,
    "id": "curl"
}

Getting Block

  • getblock

Returns information about the block with the given hash:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getblock", "params": ["eaaf8d4d27c5ce9b282e9ff870793382e14345436fac74ea40907320e50603db"]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python3 -m json.tool
{
    "result": {
        "hash": "eaaf8d4d27c5ce9b282e9ff870793382e14345436fac74ea40907320e50603db",
        "confirmations": 1,
        "strippedsize": 229,
        "size": 265,
        "weight": 952,
        "height": 2391641,
        "version": 536870912,
        "versionHex": "20000000",
        "merkleroot": "4e6a50298fb717f6356b53bf0f66fee77562c4c4d09dc0b454d0cf89168087bd",
        "tx": [
            "4e6a50298fb717f6356b53bf0f66fee77562c4c4d09dc0b454d0cf89168087bd"
        ],
        "time": 1673267350,
        "mediantime": 1673266113,
        "nonce": 32766,
        "bits": "1e0fffff",
        "difficulty": 0.0002441371325370145,
        "chainwork": "000000000000000000000000000000000000000000000000012191b962fdedf7",
        "nTx": 1,
        "previousblockhash": "9db4a06c9f7abbace253e3185eb6c65531a7b6bc520b8d52f11ea984dee8cc45"
    },
    "error": null,
    "id": "curl"
}

More info on these parameters: - Bitcoin API calls list

Managing Logging

  • logging

To view the status of logging:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "logging", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/

To enable all logging categories:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "logging", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/

To enable categories, place it on the left side of the array, and to exclude on the right side of the array, to exclude only libevent for example:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "logging", "params": [["all"], ["libevent"]]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/

To only enable only net and rpc:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "logging", "params": [["net", "rpc"], []]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/

Wallet Management

  • createwallet

Create a wallet named main:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "createwallet", "params": ["main"]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/
{"result":{"name":"main","warning":""},"error":null,"id":"curl"}

When we list our data directory we can see the files it created for the wallet:

sudo find /home/bitcoin/.bitcoin/ | grep main
/home/bitcoin/.bitcoin/testnet3/wallets/main
/home/bitcoin/.bitcoin/testnet3/wallets/main/wallet.dat
/home/bitcoin/.bitcoin/testnet3/wallets/main/db.log
/home/bitcoin/.bitcoin/testnet3/wallets/main/database
/home/bitcoin/.bitcoin/testnet3/wallets/main/database/log.0000000004
/home/bitcoin/.bitcoin/testnet3/wallets/main/database/log.0000000003
/home/bitcoin/.bitcoin/testnet3/wallets/main/.walletlock

Listing Wallets

  • listwallets

List our loaded wallets:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "listwallets", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/
{"result":["main"],"error":null,"id":"curl"}

Getting New Address

  • getnewaddress

Get a new address for our main wallet:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getnewaddress", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/main
{"result":"tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv","error":null,"id":"curl"}

Getting Addresses By Label

  • getaddressesbylabel

List the wallet addresses for our wallet:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getaddressesbylabel", "params": [""]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/main
{"result":{"tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv":{"purpose":"receive"}},"error":null,"id":"curl"}

Getting Address Info

  • getaddressinfo

Get the address info for our wallet:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getaddressinfo", "params": ["tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv"]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/main | python -m json.tool
{
    "error": null,
    "id": "curl",
    "result": {
        "address": "tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv",
        "desc": "wpkh([x/0'/0'/0']x)#k3fgqsxn",
        "hdkeypath": "m/0'/0'/0'",
        "hdmasterfingerprint": "x",
        "hdseedid": "x",
        "ischange": false,
        "ismine": true,
        "isscript": false,
        "iswatchonly": false,
        "iswitness": true,
        "labels": [
            ""
        ],
        "pubkey": "03a4xx",
        "scriptPubKey": "0014xx",
        "solvable": true,
        "timestamp": 1624551798,
        "witness_program": "11b7xx4",
        "witness_version": 0
    }
}

Loading Wallets

  • loadwallet

To load a unloaded wallet:

curl -s -u "${rpcuser}:${rpcpass}" --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "loadwallet", "params": ["nonmain"]}' -H 'content-type: text/plain;' http://127.0.0.1:18332/

Getting Wallet Info

  • getwalletinfo
curl -u "bitcoinrpc:bitcoinpass" -d '{"jsonrpc": "1.0", "id": "curltest", "method": "getwalletinfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/wallet/main

Transaction Management

If we list transactions for our wallet it should be empty:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "listtransactions", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/rpi01-main
{"result":[],"error":null,"id":"curl"}

Go to https://coinfaucet.eu/en/btc-testnet/ and send testnet btc to tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv, once the transaction is submitted run the listtransactions method again.

Other faucets that you can try: - https://testnet-faucet.mempool.co/ - https://coinfaucet.eu/en/btc-testnet/ - https://bitcoinfaucet.uo1.net/ - https://onchain.io/bitcoin-testnet-faucet - https://testnet.qc.to/ - https://tbtc.mocacinno.com/claim.php

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "listtransactions", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/rpi01-main
{"result":[],"error":null,"id":"curl"}

As you can see theres still nothing, but to add at this moment in time, the IBD process is not completed yet:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getblockchaininfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python -m json.tool | grep verificationprogress
        "verificationprogress": 0.57450649965558,

After some time we can look at the logs as one method to see how far the verification progress is:

journalctl -fu bitcoind
Jun 25 10:53:31 rpi-01 bitcoind[16198]: 2021-06-25T08:53:31Z UpdateTip: new best=00000000afb049b341ddf19d8080af6524a05f618abbf0ec51806dcef7bd5b9d height=2006268 version=0x20000000 log2_work=74.331879 tx=60315046 date='2021-06-25T08:55:11Z' progress=1.000000 cache=46.3MiB(298787txo)

And we can see its synced progress=1.000000, we can then also validate with:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getblockchaininfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | python -m json.tool | grep verificationprogress
        "verificationprogress": 0.9999985282659621,

Now we should be able to see our funds and we can run the listtransactions method:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "listtransactions", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/rpi01-main | python -m json.tool
{
    "error": null,
    "id": "curl",
    "result": [
        {
            "address": "tb1qzxmefmcpq98z42v67a80gvug2fe979r5h768yv",
            "amount": 0.01828492,
            "bip125-replaceable": "no",
            "blockhash": "0000000086003a9060e5743bfe0c7d81805a1948d6d5e326c5e3bb2f9ea83db7",
            "blockheight": 2006194,
            "blockindex": 8,
            "blocktime": 1624552612,
            "category": "receive",
            "confirmations": 75,
            "label": "",
            "time": 1624552612,
            "timereceived": 1624608999,
            "txid": "1635a05862e46a02306cfb9b5fd2f1f15a214a7227d29502550b40abdfe113d3",
            "vout": 1,
            "walletconflicts": []
        }
    ]
}

We can see the transaction, and because we are running a testnet chain, we need at least 1 confirmation, which we have 75 at the moment, so we should see the funds in our wallet:

curl -s -u "${rpcuser}:${rpcpass}" -d '{"jsonrpc": "1.0", "id": "curl", "method": "getbalance", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:18332/wallet/rpi01-main
{"result":0.01828492,"error":null,"id":"curl"}

We can also do a lookup on the txid, on a testnet blockchain explorer, like below: - https://www.blockchain.com/btc-testnet/tx/1635a05862e46a02306cfb9b5fd2f1f15a214a7227d29502550b40abdfe113d3

[WIP]