Sitemap
Aggelos K

Aggelos K

Software Engineer, Physicist, Blockchain and writing about Blockchain - Software Development - Crypto

A Step-by-Step Guide to Building Your Smart Order Router Bot with Kupo, Cardano Node, and Docker

7 min readDec 23, 2023

--

This guide provides a detailed walkthrough on setting up a Smart Order Router (SOR) using Kupo, Cardano Node, and Docker. It’s designed for those with a basic understanding of these technologies and aims to streamline the SOR deployment process.

Contents:

1. Prerequisites

  • Required to install tools and software: Git, Docker

2. Setting Up the SOR Environment

  • Cloning the SOR repository from GitHub.
  • Installing and configuring the Cardano Node.
  • Steps for installing Kupo on your local machine.

3. Creating and Configuring a Wallet

  • Generating signing keys using Cardano CLI.
  • Building a wallet address for the mainnet.
  • Extracting the CBOR Hex value for the signing key.

4. Preparing Collateral UTXO Reference

  • Sending ADA to the newly created wallet.
  • Identifying and setting the COLLATERAL_UTXO_REF.

5. Running Kupo Instance

  • Editing and running the kupo-mainnet.sh script based on your configuration or create your own kupo-service to run independently
  • Confirming successful Kupo instance launch.

6. Building and Running the SOR Using Docker

  • Building the SOR Docker image.
  • Running the SOR with the customized Docker command.

7. Monitoring and Troubleshooting

  • How to view logs and manage the SOR instance.

8. Additional Resources

  • Links to Smart Order Router, Kupo, Cardano Node documentation for deeper insights.

Let’s start.

Assuming that your want to run your SOR on Linux environment

Install Git

sudo apt update
sudo apt install git
git --version

Install Docker

Installing docker depends on your operation system.
I would recommend you follow the official installation guide based on your system.
Follow the guidance from the link here: https://docs.docker.com/engine/install/

Setting Up the SOR Environment

Cloning the SOR repository from GitHub.

git clone https://github.com/geniusyield/smart-order-router.git SOR

Run cardano node

I would recommend you following one of these documentation regarding cardano node:

  • Installation with docker here
  • Installation by creating a service for setting up your node , here (Recommended to simplify your own SOR installation)

Installation of Kupo

Installation can be done via 3 different paths:

  • From pre-compiled executables
  • From docker
  • From source

I chose the first option, so here are the steps that I did:

Donwload Kupo:

wget https://github.com/CardanoSolutions/kupo/releases/tag/v2.7/kupo-2.7.2-arm64-Linux.tar.gz

Extract the downloaded tar.gz file:

tar -xzvf kupo-2.7.2-arm64-Linux.tar.gz

Move the Kupo binary to a directory in your PATH, such as /usr/local/bin:

mv kupo-2.7.2-arm64-Linux/bin/kupo /usr/local/bin/

Make Kupo binary executyable:

chmod +x /usr/local/bin/kupo

Ensure Kupo installation is working

kupo --version

3. Creating and Configuring a Wallet

  • Generating signing keys using Cardano CLI.
cd node/

./cardano-cli address key-gen \
--verification-key-file bot.vkey \
--signing-key-file bot.skey

Above command will create the bot.skey, bot.vkey which are the the private signing key, the verification key of the bot respectively. Then you need to create an address for the mainnet based on the bot.vkey which is already created by following this command:

  • Building a wallet address for the mainnet.
./cardano-cli address build \
--payment-verification-key-file bot.vkey \
--mainnet \
--out-file bot.addr
  • Extracting the CBOR Hex value for the signing key.

The bot.skey that you created above contains the cborHex value which is going to be used afterwards when we need to set PAYMENT_SIGNING_KEY_CBOR_HEX value.

Get Aggelos K’s stories in your inbox

Join Medium for free to get updates from this writer.

So in order to find its value, you can do the command under node/ folder as well (this command can be done wherever you have saved your bot addresses and private/verification keys):

cat bot.skey | jq -r '.cborHex'

This value should not be shared to anyone but is going to be used later.

4. Preparing Collateral UTXO Reference

Sending ADA to the newly created wallet

In this stage you need to send at least 5 ADA in your newly created wallet, in one or more transactions , which one of them is going to be used for collateral.

Identifying and setting the COLLATERAL_UTXO_REF

After sending the ADA to your wallet, you can query the address to see the utxos:

./cardano-cli query utxo --address $(cat bot.addr) --mainnet --socket-path  /root/node/sockets/node.socket

where you will see something like this:

TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
fbfa56e74a0ed92e53c6ed94dc290610d918760e25a700c5a96aee4c62562286 0 5000000 lovelace + TxOutDatumNone

Assign the result to COLLATERAL_UTXO_REF (TxHash#Tx), for example: (COLLATERAL_UTXO_REF=fbfa56e74a0ed92e53c6ed94dc290610d918760e25a700c5a96aee4c62562286#0)

5. Running Kupo Instance

  • Editing and running the kupo-mainnet.sh script based on your configuration OR create your own kupo-service to run independently. I will write both ways below so select based on your preference.
  • Goal of this step is to run your own Kupo Instance either by updating the script under SOR/scripts/kupo-mainnet.sh (simpler) OR by creating a kupo service (recommended)

Update your own kupo-mainnet.sh

cd SOR/scripts/
nano kupo-mainnet.sh
FROM_BABBAGE=72316796.c58a24ba8203e7629422a24d9dc68ce2ed495420bf40d9dab124373655161a20
MATCH_ORDERS=22f6999d4effc0ade05f6e1a70b702c65d6b3cdf0e301e4a8267f585.*
MATCH_BOT=<your bot.addr here>
MATCH_MINTING_POLICY_REF=1@062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea
MATCH_VALIDATOR_REF=2@062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea
MATCH_CONFIG_ADDR=addr1w9zr09hgj7z6vz3d7wnxw0u4x30arsp5k8avlcm84utptls8uqd0z

kupo \
--host 0.0.0.0 \
--port 1442 \
--node-socket /root/node/sockets/node.socket \
--node-config /root/node/configuration/cardano/mainnet-config.json \
--since $FROM_BABBAGE \
--defer-db-indexes \
--match $MATCH_ORDERS \
--match $MATCH_BOT \
--match $MATCH_MINTING_POLICY_REF \
--match $MATCH_VALIDATOR_REF \
--match $MATCH_CONFIG_ADDR \
--prune-utxo \
--workdir /root/node/kupo/sor/db

Above we updated the script by setting variables that will be used to run Kupo instance and also to point to your local cardano node configuration and node socket path. Which means that whatever you see above next to — node-socket , — node-config and — workdir should be updated based on your local environment respectively.

Confirming successful Kupo instance launch.

./kupo-mainnet.sh

OR

Create your own Kupo Service

Create a New Service File: Open a new service file in the /etc/systemd/system/ directory with your preferred text editor. For example, you can use nano:

sudo nano /etc/systemd/system/kupo.service

Add Service Configuration: In the service file, add the following configuration (adjust paths and options according to your setup):

[Unit]
Description=Kupo Service
After=network.target

[Service]
ExecStart=/usr/local/bin/kupo [Your Kupo Arguments Here]
WorkingDirectory=/root/SOR/scripts
Restart=always
User=root

[Install]
WantedBy=multi-user.target

Your arguments should be the same arguments as you would put them in kupo-mainnet.sh so like this in above case:

[Service]
ExecStart=/usr/local/bin/kupo --host 0.0.0.0 --port 1442 --node-socket /root/node/sockets/node.socket --node-config /root/node/configuration/cardano/mainnet-config.json --since 72316796.c58a24ba8203e7629422a24d9dc68ce2ed495420bf40d9dab124373655161a20 --defer-db-indexes --match 22f6999d4effc0ade05f6e1a70b702c65d6b3cdf0e301e4a8267f585.* --match <YOUR BOT ADDRESS HERE> --match 1@062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea --match 2@062f97b0e64130bc18b4a227299a62d6d59a4ea852a4c90db3de2204a2cd19ea --match addr1w9zr09hgj7z6vz3d7wnxw0u4x30arsp5k8avlcm84utptls8uqd0z --prune-utxo --workdir /root/node/kupo/sor/db

but instead of <YOUR BOT ADDRESS HERE> you should put your own bot.addr.

Also, Replace /usr/local/bin/kupo with the actual path to the kupo binary if it's different.

Reload Systemd and Enable Service: After saving and closing the file:

sudo systemctl daemon-reload
sudo systemctl enable kupo.service
sudo systemctl start kupo.service

Check Status: To ensure the service is running correctly:

sudo systemctl status kupo.service

or you can check the latest 100 lines of the logs like this:

journalctl -u kupo.service --lines=100

Normally you have to see something like this:

Press enter or click to view image in full size

6. Building and Running the SOR Using Docker

Since cardano node and Kupo instance are running properly, you are close to run your own SOR:

Building the SOR Docker image

cd ~
cd SOR
docker build .

Running the SOR with the customized Docker command

Update values based on your configuration of:

PAYMENT_SIGNING_KEY_CBOR_HEX= - follow the instructions above and put the correct value-
COLLATERAL_UTXO_REF= - follow the instructions above and put the correct value -
KUPO_URL=http://your.server.ip.here:1442
CARDANO_NODE_SOCKET_PATH=/root/node/sockets/node.socket
CARDANO_NETWORK=mainnet

PAYMENT_SIGNING_KEY_CBOR_HEX:This is the CBOR Hex representation of your payment signing key. You already have the bot.skey file, so you need to extract the cborHex value from it.

COLLATERAL_UTXO_REF: This refers to a specific unspent transaction output (UTXO) that the bot will use as collateral. You need to identify a UTXO from the wallet address used by the bot. You can use the cardano-cli query utxo command to list UTXOs for your bot’s address, as I have shown above.

You are ready to launch your Smart Order Router (SOR) bot:

Firstly copy the docker image that you build before after executing below command:

docker image ls

Then run your own SOR with docker by following this command

docker run -it -d \
-e BOTC_SKEY="{\"cborHex\": \"$PAYMENT_SIGNING_KEY_CBOR_HEX\", \"type\": \"PaymentSigningKeyShelley_ed25519\", \"description\": \"Payment Signing Key\"}" \
-e BOTC_COLLATERAL="$COLLATERAL_UTXO_REF" \
-e BOTC_CONFIG="{\"coreProvider\": { \"socketPath\": \"/cardano/node/socket\", \"kupoUrl\": \"$KUPO_URL\" }, \"networkId\": \"$CARDANO_NETWORK\", \"logging\": [{ \"type\": { \"tag\": \"stderr\" }, \"severity\": \"Info\", \"verbosity\": \"V2\" }], \"utxoCacheEnable\": false }" \
-v $CARDANO_NODE_SOCKET_PATH:/cardano/node/socket \
0e57bdd15e6b

where 0e57bdd15e6b is an example of the IMAGE ID of the last build image for SOR. On your environment will be found with the result of the command above about ```docker image ls```

And that was it. Your SOR should run from now on. Your SOR should expect matches from this moment. Good luck!

Press enter or click to view image in full size

7. Monitoring and Troubleshooting

  • How to view logs and manage the SOR instance.
docker ps -a
docker logs <CONTAINER ID>

8. Additional Resources

Many credits for the above documentation goes also to Hummus for his contribution to setting up the bot and for the technical documentation.

Genius Yield — Genius Yield Greece — Genius Yield Italia — Genius X

--

--