Liquid Bitcoin (L-BTC) Node for CAS

Liquid Bitcoin (L-BTC) Node for CAS

GENERAL BYTES incorporated support for the Liquid Network in CAS version 20250901.


The Liquid Network is an open-source Bitcoin sidechain and layer-2 solution interoperable with Lightning that enables faster, more confidential bitcoin transactions and the issuance and exchange of digital assets like stablecoins, tokenized securities, and bonds.”

More information from: https://liquid.net/

Table of Contents


Overview

Providing Liquid Bitcoin (L_BTC) on your BATMs requires the following steps:

  1. Install a Bitcoin Core node.

  2. Wait for the Bitcoin Core node to sync with Bitcoin network.

  3. Install the Elements node and connect it to Bitcoin Core.

  4. Fund your node.

  5. Enable secure connection between you CAS and the Elements node.

  6. Configure the “Liquid Network Bitcoin - Elements Core” Crypto Setting.


Install Bitcoin Core

Instructions: https://generalbytes.atlassian.net/wiki/x/2oDoO

The Bitcoin Core node must be fully synced and operational before proceeding to install Elements. This may take days, or even a week - depending upon your system configuration and network speed.


Elements node installation

  1. Install Ubuntu 24.04 or newer. Running bitcoind and elementsd at the same time requires 16 GB of RAM and will consume (as of October 2025) at least 1 TB of drive space.

  2. Download release for Linux x64 from here: https://github.com/ElementsProject/elements/releases . At the time of this article creation latest release file was elements-23.3.0-x86_64-linux-gnu.tar.gz.

wget https://github.com/ElementsProject/elements/releases/download/elements-23.3.0/elements-23.3.0-x86_64-linux-gnu.tar.gz tar -xzvf elements-23.3.0-x86_64-linux-gnu.tar.gz
  1. Run elementsd

cd elements-23.3.0/bin ./elementsd
  1. Wait for elements to synchronize - this may take 2+ days.

  2. Create your first elements wallet:

./elements-cli createwallet main
  1. Check that wallet was properly created

./elements-cli -rpcwallet=main getwalletinfo { "walletname": "main", "walletversion": 169900, "format": "bdb", "balance": { "bitcoin": 0.00000000 }, "unconfirmed_balance": { "bitcoin": 0.00000000 }, "immature_balance": { "bitcoin": 0.00000000 }, "txcount": 0, "keypoololdest": 1754416920, "keypoolsize": 1000, "hdseedid": "c0e448000c131135c89f777d6632dc729dcbe80e", "keypoolsize_hd_internal": 1000, "paytxfee": 0.00000000, "private_keys_enabled": true, "avoid_reuse": false, "scanning": false, "descriptors": false, "external_signer": false }
  1. View the current receiving addresses of our main wallet:

./elements-cli -rpcwallet=main listreceivedbyaddress
  • Example response (it will be empty as there is no wallet yet):

[ ]
  1. Get your first new address. This L-BTC address is where we will receive our L-BTC:

./elements-cli getnewaddress
  • Example response:

lq1qqdy4kz0p9k05mgzlv2eu7l0nzfzka7n5el9txgxx7ps6fldvtx2x6gj4ual0kxhfzruc39e9pf9f5gqm9vfqzskwl4xdetjyp
  1. First create a pegin bitcoin wallet on your node where you will be receiving the BTC that will be converted to L-BTC. Run the following command on your Bitcoin node:

./bitcoin-cli createwallet pegin
  • Typical result:

{ "name": "pegin" }
  1. Get your first pegin address:

./elements-cli getpeginaddress
  • Example response:

{ "mainchain_address": "bc1qhhvyluwua7552wqhjv23xt5pdnvlumqmad0ngkwtg7whtrn4hh8sfwhpc3", "claim_script": "00141923225c399212b8772dc594d2c70af143b01a10" }
  1. Now you can send your BTC (start with small amount first) to a pegin address (in our case it was bc1qhhvyluwua7552wqhjv23xt5pdnvlumqmad0ngkwtg7whtrn4hh8sfwhpc3).

    1. In our example the transfer was performed in transaction: 240e62ef23fa4c3837e17e578c07b6a71d2131b0dde15762403d4c81a60f0e8e.

  2. You must wait for 100 confirmations (about 16 hours) for the BTC to be pegged.

  3. Get the raw transaction. When you don’t have txindex=1 uncommented in bitcoin.conf then you need to also provide format(0) and blockhash of block in which was transaction included. In your example transaction 240e62ef23fa4c3837e17e578c07b6a71d2131b0dde15762403d4c81a60f0e8e was included in block #908772 that has this blockhash: 00000000000000000001c272398a39820e1a3feb9a153fb2eb44db5dc51189cb.

./bitcoin-cli getrawtransaction 240e62ef23fa4c3837e17e578c07b6a71d2131b0dde15762403d4c81a60f0e8e 0 00000000000000000001c272398a39820e1a3feb9a153fb2eb44db5dc51189cb
  • Example response:

02000000016132a5b22818d229b345c24613592285a24d77c14b3a01e9aaa3e2cd63935318000000006a47304402206ae69b9d99c63e27b751392cb933fa9cfd42ae1c93dd820e911fa20ddca90e2502206d15ca0ae3c12e1f3f3c52c45f2c27a5a995b167cdc00794522cf7f8903e261e012103967318c3e5e5a4c36e4f874077d4b5d3cbd372473db31e12a2d9de286e4be82cfdffffff01c344000000000000220020bdd84ff1dcefa94538179315132e816cd9fe6c1beb5f3459cb479d758e75bdcf00000000
  1. Once you have a raw transaction then you can generate a “txoutproof”. gettxoutproof produces a Merkle proof that shows your transaction is included in a specific Bitcoin block:

./bitcoin-cli gettxoutproof '["240e62ef23fa4c3837e17e578c07b6a71d2131b0dde15762403d4c81a60f0e8e"]' 00000000000000000001c272398a39820e1a3feb9a153fb2eb44db5dc51189cb
  • Example response:

0000ff3f4d27d84a694c25d27c81eafbea0425769b7cbf61ec2c000000000000000000003b0fd83de1343e4f7c7e3f3f4ee017af99992852503ca3fb0c313c60579f2717bb5a92689e3402177aee7e5e550300000bec7a16609482bf507980c0c8f36dfb48d94514e5da8925168fca92f8c0138a4d1ee08c837336e8805fca007cea9381a95ce0df34d3888beddfd20c233151c4a1ec672a1ffd29ca5df057b45adb2f6cc58f294b72163d106a509d00a3d667a0218e0e0fa6814c3d406257e1ddb031211da7b6078c577ee137384cfa23ef620e248562cc7b57983a85284a102acfcedbb7796dd7f14fd2d3b678aafbf966604b5f875cc5b5d886fa4ccdce20624815bc500f97d6a80aa7ecd002a0c000d80b36eaace40794842ce47d094f5901de44fdf949729e28c10a71c1e299dc8119f019ab449bfcfff676e3ca01896b8b03129d5d6a53e364e66bf5d6b7d6551bb9c5427c7a8954a8d9f5cfcf676cadca3d11548492697dd37d662d2733ff1d6349d12d07ab52b2284a7b362b923274b05c0d719c3ac12fa334109d3805b800d793b5df426aeb5dfd8ccdc2bc0da9db8af315ec7ac776d2b358531c0c3da2ba23a6d4918003ef2b00
  1. Claim Liquid bitcoin on our elements node. We will provide the rawtxoutput which was used to fund the wallet, a proof that the transaction was included to a block and a claim script. Note that we needed to add as a third parameter a claimscript that elementsnode returned when it generated the address for us in previous step. Returned value is a txid on liquid chain.

./elements-cli claimpegin 02000000016132a5b22818d229b345c24613592285a24d77c14b3a01e9aaa3e2cd63935318000000006a47304402206ae69b9d99c63e27b751392cb933fa9cfd42ae1c93dd820e911fa20ddca90e2502206d15ca0ae3c12e1f3f3c52c45f2c27a5a995b167cdc00794522cf7f8903e261e012103967318c3e5e5a4c36e4f874077d4b5d3cbd372473db31e12a2d9de286e4be82cfdffffff01c344000000000000220020bdd84ff1dcefa94538179315132e816cd9fe6c1beb5f3459cb479d758e75bdcf00000000 0000ff3f4d27d84a694c25d27c81eafbea0425769b7cbf61ec2c000000000000000000003b0fd83de1343e4f7c7e3f3f4ee017af99992852503ca3fb0c313c60579f2717bb5a92689e3402177aee7e5e550300000bec7a16609482bf507980c0c8f36dfb48d94514e5da8925168fca92f8c0138a4d1ee08c837336e8805fca007cea9381a95ce0df34d3888beddfd20c233151c4a1ec672a1ffd29ca5df057b45adb2f6cc58f294b72163d106a509d00a3d667a0218e0e0fa6814c3d406257e1ddb031211da7b6078c577ee137384cfa23ef620e248562cc7b57983a85284a102acfcedbb7796dd7f14fd2d3b678aafbf966604b5f875cc5b5d886fa4ccdce20624815bc500f97d6a80aa7ecd002a0c000d80b36eaace40794842ce47d094f5901de44fdf949729e28c10a71c1e299dc8119f019ab449bfcfff676e3ca01896b8b03129d5d6a53e364e66bf5d6b7d6551bb9c5427c7a8954a8d9f5cfcf676cadca3d11548492697dd37d662d2733ff1d6349d12d07ab52b2284a7b362b923274b05c0d719c3ac12fa334109d3805b800d793b5df426aeb5dfd8ccdc2bc0da9db8af315ec7ac776d2b358531c0c3da2ba23a6d4918003ef2b00 00141923225c399212b8772dc594d2c70af143b01a10
  • Example response:

20ea7b89adbf0c4aab3bb7b4d7b42dd3063f4cd1076bba64c8c24f21c4f22dc6
  1. Check your balance. BTC should now be listed. Type this:

./elements-cli getwalletinfo
  • This is a typical response:

{ "walletname": "main", "walletversion": 169900, "format": "bdb", "balance": { "bitcoin": 0.00017565 }, "unconfirmed_balance": { "bitcoin": 0.00000000 }, "immature_balance": { "bitcoin": 0.00000000 }, "txcount": 1, "keypoololdest": 1754416920, "keypoolsize": 999, "hdseedid": "c0e448000c131135c89f777d6632dc729dcbe80e", "keypoolsize_hd_internal": 1000, "paytxfee": 0.00000000, "private_keys_enabled": true, "avoid_reuse": false, "scanning": false, "descriptors": false, "external_signer": false }

Setup a secure tunnel for encrypted communication.

Your CAS server and this node must have a secure line. Your password and other sensitive information will be passed back & forth. Encrypt (and thus protect) this communication by using a secure SSH tunnel.

The GB Wallet Tunnel is recommended.

General Bytes has incorporated an open-source SSH client into CAS.

Click here for instructions to install the GB Wallet Tunnel Server on this node.

Alternative (unsupported):

Build an SSH tunnel (instead of the GB Wallet Tunnel), see: https://generalbytes.atlassian.net/l/cp/b7j5AVHA

With those instructions,

  • set FORWARDED_PORT=8332 for Bitcoin Core, and using the script again,

  • set FORWARDED_PORT=7042 for the Liquid Network Elements Node.


Connect Liquid Network Node in CAS

Once you have the Liquid node installed, synchronized, have a balance in it, and the node is accessible via the GB Wallet Tunnel - configure CAS to connect to your node.

Enabling RPC on node

Before configuring CAS we need to make sure that the RPC (Remote Procedure Call) of your elementsd node:

  1. requires a username and password (choose wisely),

  2. listens on the correct IP address (rpcbind),

    1. You may permit multiple rpcbind entries as needed.

  3. and accepts connections only from permitted IP addresses.

    1. You may specify multiple rpcallowip entries if needed.

DO NOT allow/specify public IP addresses!

Add the following lines into your ~/.elements/elements.conf file. Make sure you choose a different password and username. If the file doesn’t exist you will need to create it:

sudo nano ~/.elements/elements.conf

Example settings for the file ~/.elements/elements.conf:

server=1 # enable RPC server txindex=1 rpcuser=myuser rpcpassword=myPAZs2345x!2 rpcbind=127.0.0.1 rpcallowip=127.0.0.1
  • Use Ctrl+X to save the file, and

  • then restart elementsd to have the new settings take effect.

You can test that your RPC is configured properly by running the following line:

curl --user myuser:myPAZs2345x!2 --data-binary '{"jsonrpc":"1.0","id":"curl","method":"getblockchaininfo","params":[]}' -H 'content-type:text/plain;' http://127.0.0.1:7041/
  • Replace myuser:myPAZs2345x!2 with your actual username and password.

To check the balance you can run this line:

curl --user myuser:myPAZs2345x!2 --data-binary '{"jsonrpc":"1.0","id":"curl","method":"getbalance","params":["main"]}' -H 'content-type:text/plain;' http://127.0.0.1:7041/

Make sure you have your wallet loaded when calling the RPC.

Load the wallet by calling:

./bitcoin-cli loadwallet main
  • You need to load the wallet each time after starting elementsd.

Configuring the Hot Wallet in CAS

Create a Crypto Setting for L-BTC and specify the parameters for your node.

image-20250924-114039.png
  • Hot Wallet Buy: select Liquid Network Bitcoin - Elements Core

  • Parameters: protocol : user : password : host : port : wallet

    • No spaces are permitted between the parameters (they’re used above only for clarification).

    • Example: http:myuser:myPAZs2345x!2:123.321.123.321:7041:main

      • myuser is the username that you specified in your elements.conf above, and

      • myPAZs2345x!2 is the password from the same file.

      • The IP address 123.321.123.321 is the public IP address of your node server on which the wallet tunnel (and elementsd) resides.

      • 7041 is the standard port for elementsd node RPC.

      • main is the name of your wallet on the node.

        • Make sure you load the wallet first as we mentioned above.

        • You need to load this wallet during every startup of elementsd.

  • Wallet Tunnel Password: this is automatically generated for you (and provided to you) during the GB Wallet Tunnel server installation as described here (if used).


Firewall Configuration

Configure the firewall after you’ve successfully connected and tested your CAS Crypto Setting.

This node needs to expose these ports:

  • 22 (SSH),

  • 22222 (GB Wallet Tunnel)

  • 8332 (Bitcoin Core)

  • 7042 (Liquid Network Elements Node)

  • Block off all other access/ports to reduce malicious actors' abuse/attacks on your node.

UFW, or Uncomplicated FireWall, is a simplified firewall management interface. UFW is included automatically with Ubuntu.

  1. Check to see if UFW is already enabled and running:

sudo ufw status
  • If UFW is enabled and working, it will report the active rules of allowed connections to your server - otherwise you'll see something like this:

  • Fresh/new systems will normally be inactive (the system is unprotected).

  • If it is not installed, install it now using: sudo apt update && sudo apt install ufw

  • If UFW is active, then this procedure will erase that previous configuration and rewrite the rules.

Reset & deny all incoming connections by default:

sudo ufw reset
  • This will erase any/all previous UFW configuration.

Deny all public access to all ports:

sudo ufw default deny incoming
  • Now we’re left to specify the exceptions (the “rules”).

Allow incoming TCP connections on ports 22, 22222, 8332, and 7042

sudo ufw allow 22/tcp sudo ufw allow 22222/tcp sudo ufw allow 8332/tcp sudo ufw allow 7042/tcp

Finally, enable & reload UFW to apply the new rules:

sudo ufw enable sudo ufw reload

Assuming your commands succeeded, your node should now be protected by UFW.


Copyright © 2020-2026 General Bytes USA LLC