Launch a local development environment
Goal
This article will guide you to launch a local environment for developing Hathor clients, integrations, wallets, blueprints, nano contracts, and DApps.
Requirements
- Docker v27.3.1
- Docker compose v2.29.7
- Available ports (not in use): 8000, 8080, 9000, 9080
Step-by-step
- Run Hathor system sandbox.
- Test sandbox.
- Test nano contracts.
- Test blueprint deployment.
- Test end-user experience.
This sandbox is a local instance of Hathor system, fully isolated from public Hathor Network mainnet and testnet, and consists of four interconnected components:
- Full node (Hathor core)
- Transaction mining service
- CPU miner
- Headless wallet
Step 1: run Hathor system sandbox
- Install Hathor core from source code
- Open a terminal.
- Change the working directory to where you installed Hathor core — i.e., the parent directory of
hathor-core
. - Empty the subdirectory
data
. - Change the working directory to its child
hathor-core
: - Switch the repository
hathor-core
to the SDK branch:
git switch experimental/nano-testnet-v1.6.1
- Open the file
hathor/conf/nano_testnet.yml
. - At the end of the file, add the environment variable
REWARD_SPEND_MIN_BLOCKS: 3
. - Start the full node with data persistence:
poetry run hathor-cli run_node --status 8080 --nano-testnet --data ../data --wallet-index --x-localhost-only --allow-mining-without-peers --nc-history-index
Keep this terminal open to monitor the full node's output log. This allows you to confirm that the blockchain is receiving new blocks correctly and to check for any errors in executing nano contract methods.
- Open a new terminal.
- Change the working directory to where you installed the full node — namely,
hathor-core
anddata
. - Create the file
docker-compose.yml
with the configuration of your development environment:
services:
cpu-miner:
image: hathornetwork/cpuminer
network_mode: host
command: >
--algo sha256d
--threads 1
--coinbase-addr WiGFcSYHhfRqWJ7PXYvhjULXtXCYD1VFdS
--url stratum+tcp://localhost:9000
tx-mining-service:
image: hathornetwork/tx-mining-service
network_mode: host
command: >
--stratum-port 9000
--api-port 9080
--testnet
--address WiGFcSYHhfRqWJ7PXYvhjULXtXCYD1VFdS
http://localhost:8080
headless-wallet:
image: hathornetwork/hathor-wallet-headless
network_mode: host
command: >
--seeds 'alice bob'
--seed_alice 'music endless reduce plunge accident multiply two curtain match balance present belt price burger mother crisp sock tumble napkin leopard unit upset original cause'
--seed_bob 'flee tortoise payment hockey region chicken park dwarf ship elite whale club color survey diagram seminar hair hill wealth spike egg ramp burst crucial'
--network testnet
--server http://localhost:8080/v1a/
--tx_mining_url http://localhost:9080
- Start all services that, together with the full node, make up your Hathor system sandbox:
docker compose up -d
- Confirm that all three services managed via Docker have started successfully:
docker compose ps
Step 2: test sandbox
If your Hathor system sandbox is working properly, you should see blocks being mined in the full node log after approximately 40 seconds. Next, you need to test if the wallets are interacting correctly with the blockchain and if transactions are being processed properly.
- Start Alice's wallet:
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"wallet-id": "alice",
"seedKey": "alice"
}' \
http://localhost:8000/start | jq
- Start Bob's wallet:
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"wallet-id": "bob",
"seedKey": "bob"
}' \
http://localhost:8000/start | jq
Alice's wallet is configured (in docker-compose.yml
) to receive block mining rewards in HTR. You will need these funds to test the system and afterward your operations.
- Check Alice's balance:
curl -X GET \
-H "X-Wallet-Id: alice" \
http://localhost:8000/wallet/balance | jq
- Use Alice's wallet to create a token:
curl -X POST \
-H "X-Wallet-Id: alice" \
-H "Content-type: application/json" \
-d '{
"name": "alice-coin",
"symbol": "ALICE",
"amount": 1000
}' \
http://localhost:8000/wallet/create-token | jq
A token is identified by its token UID, which is the hash of the transaction that created it. In the following example, it is 00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669
:
{
"success": true,
"configurationString": "[alice-coin:ALICE:00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669:f57c591a]",
"inputs": [ ... ],
"outputs": [ ... ],
"signalBits": 0,
"version": 2,
"weight": 19.362482584834382,
"nonce": 2073499,
"timestamp": 1733336251,
"parents": [ ... ],
"tokens": [],
"hash": "00000943573723a28e3dd980c10e08419d0e00bc647a95f4ca9671ebea7d5669",
"_dataToSignCache": { ... },
"name": "alice-coin",
"symbol": "ALICE"
}
<Placeholders>
: in the code samples of this article, as in all Hathor docs, <placeholders>
are always wrapped by angle brackets < >
. You shall interpret or replace a <placeholder>
with a value according to the context. Whenever replacing a <placeholder>
like this one with a value, do not wrap the value with quotes. Quotes, when necessary, will be indicated, wrapping the "<placeholder>"
like this one.
- Send an amount of the created token from Alice to Bob, replacing
<newly_created_token_UID>
with the hash of the resulting transaction from the previous substep:
curl -X POST \
-H "X-Wallet-Id: alice" \
-H "Content-Type: application/json" \
-d '{
"address" : "WQvVwRACunxaXuvkeC7kDiW16C8SSBkf9q",
"value" : 100,
"token": "<newly_created_token_UID>"
}' \
http://localhost:8000/wallet/simple-send-tx | jq
- Confirm that Bob received the transfer from Alice, replacing
<newly_created_token_UID>
with the UID of the created token:
curl -X GET \
-H "X-Wallet-Id: bob" \
http://localhost:8000/wallet/balance?token=<newly_created_token_UID> | jq
Step 3: test nano contracts
- Use Alice's wallet to create a nano contract from the
bet blueprint
, replacing<newly_created_token_UID>
with the UID of the created token:
curl -X POST \
-H "X-Wallet-Id: alice" \
-H 'Content-Type: application/json' \
-d '{
"blueprint_id": "3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595",
"address": "WiGFcSYHhfRqWJ7PXYvhjULXtXCYD1VFdS",
"data": {
"actions": [],
"args": [
"0000298f16599418b0475762c9ce570fe966fd8a62fd933888a96a16c0b893b7",
"<newly_created_token_UID>",
1891123200
]
}
}' \
http://localhost:8000/wallet/nano-contracts/create | jq
Analogous to the token UID, the contract ID is the hash of the transaction that created the contract.
- Use Alice's wallet to execute the contract, replacing
<newly_created_token_UID>
with the token used in the previous substep, and<newly_created_contract_ID>
with the hash of the corresponding resulting transaction:
curl -X POST \
-H "X-Wallet-Id: alice" \
-H 'Content-Type: application/json' \
-d '{
"nc_id": "<newly_created_contract_ID>",
"method": "bet",
"address": "WiGFcSYHhfRqWJ7PXYvhjULXtXCYD1VFdS",
"data": {
"actions": [
{
"type": "deposit",
"token": "<newly_created_token_UID>",
"amount": "100"
}
],
"args": [
"WiGFcSYHhfRqWJ7PXYvhjULXtXCYD1VFdS",
"Real-Madrid2x2Barcelona"
]
}
}' \
http://localhost:8000/wallet/nano-contracts/execute | jq
The contract history lists all transactions that executed the contract. Transactions whose contract execution was unsuccessful will be marked as voided.
- Check the contract history to verify whether the contract execution in the previous step was successful, replacing
<newly_created_contract_ID>
with the respective contract ID:
curl -X GET \
-H "X-Wallet-Id: alice" \
http://localhost:8000/wallet/nano-contracts/history?id=<ID_contract> | jq
Step 4: test blueprint deployment
This step is specific to developing new blueprints.
- Go to the full node's output terminal.
- Stop the full node.
- Open the file
hathor/nanocontracts/blueprints/__init__.py
. - Add your blueprint to the catalog of built-in blueprints:
from typing import TYPE_CHECKING, Type
from hathor.nanocontracts.blueprints.bet import Bet
from hathor.nanocontracts.blueprints.dozer_pool import Dozer_Pool
from hathor.nanocontracts.blueprints.swap_demo import SwapDemo
from hathor.nanocontracts.blueprints.your_blueprint import YourBlueprint
if TYPE_CHECKING:
from hathor.nanocontracts.blueprint import Blueprint
_blueprints_mapper: dict[str, Type["Blueprint"]] = {
"Bet": Bet,
"Dozer_Pool": Dozer_Pool,
"SwapDemo": SwapDemo,
"YourBlueprint": YourBlueprint
}
__all__ = [
"Bet",
"Dozer_Pool",
"SwapDemo",
"YourBlueprint"
]
- Open the file
hathor/conf/nano_testnet.yml
. - Define the blueprint ID by appending the following line and replacing only the blueprint name:
...
# Genesis stuff
...
# tx weight parameters. With these settings tx weight is always 8
...
BLUEPRINTS:
3cb032600bdf7db784800e4ea911b10676fa2f67591f82bb62628c234e771595: Bet
27db2b0b1a943c2714fb19d190ce87dc0094bba463b26452dd98de21a42e96a0: Dozer_Pool
0000298f16599418b0475762c9ce570fe966fd8a62fd933888a96a16c0b893b7: SwapDemo
41c4c4f09455f89a00345c8ea50c166d7e41cf80952e76db41f5d7a3044298e7: YourBlueprint
REWARD_SPEND_MIN_BLOCKS: 3
A blueprint ID is a 32-byte hexadecimal integer. To add more blueprints, generate and use random 32-byte hexadecimal integers.
- Restart the full node and test the new blueprint, as you did in the previous step with the bet blueprint.
Step 5: test end-user experience
This step is specific to developing DApps.
To test your DApp's user experience, you need to add Hathor desktop wallet to your local development environment.
- Install Hathor desktop wallet.
- Start Hathor desktop wallet.
- Initialize Alice's wallet by importing her seed:
music endless reduce plunge accident multiply two curtain match balance present belt price burger mother crisp sock tumble napkin leopard unit upset original cause
- Connect the wallet to your sandbox:
- Navigate to Settings.
- Click Change network to open Network Settings.
- In the dropdown menu, select Custom network.
- Set Node URL to
http://localhost:8080/v1a/
. - Set Transaction Mining Service URL to
http://localhost:9080
. - Leave all other fields blank.
- Click Connect to save configuration.
Task completed
You now have a complete local development environment to work with Hathor platform. The full node exposes its HTTP API on port 8080. To monitor its status, open a browser and navigate to http://localhost:8080/v1a/status/. The headless wallet exposes its HTTP API on port 8000. Note that only the main features of Hathor technology have been tested. To know how to test other features, see Hathor headless wallet pathway.