Quick start
Run a regtest node, mine spendable coins, and send a payment with the SDK. Regtest has no
retargeting (blocks are instant to mine), its own address prefix rarrk, and its API on port
28332. See Network parameters.
1. Start a node
# From the repository root: one .env with fresh secrets and a devnet miner key
./all_svc/arrekta-compose.sh init-env
./all_svc/arrekta-compose.sh build core core-rs
# 3 nodes: 2 Rust (node-1 mines every 10 s), 1 Python reference
./all_svc/arrekta-compose.sh up
# End-to-end check, including cross-implementation agreement
./all_svc/arrekta-compose.sh smokecd node-rs && cargo build --release -p arrekta-node
ARREKTA_NETWORK=regtest \
ARREKTA_DATA_DIR=./regtest-data \
ARREKTA_ADMIN_TOKEN=changeme \
./target/release/arrekta-node-rscd core
uv venv -p python3.13 .venv && uv pip install -p .venv/bin/python -e ".[dev]"
ARREKTA_NETWORK=regtest ARREKTA_ADMIN_TOKEN=changeme .venv/bin/arrekta-nodeBoth implementations read the same ARREKTA_* environment variables (full list in
Run a node). The Compose devnet publishes node-1's API on
127.0.0.1:28332, node-2 on 28342 and the Python node on 28352.
Check it is up:
curl -s http://127.0.0.1:28332/v1/chain2. Create a key and mine to it
Coinbase outputs mature after 100 blocks, so mine 101 blocks to get one spendable coinbase.
# The reference wallet CLI (installed with core/)
core/.venv/bin/arrekta-wallet new-seed alice.seed
ADDR=$(core/.venv/bin/arrekta-wallet --seed alice.seed address)
# Admin route, protected by ARREKTA_ADMIN_TOKEN (regtest/testnet only)
curl -s -X POST http://127.0.0.1:28332/v1/admin/mine \
-H "Authorization: Bearer changeme" -H 'content-type: application/json' \
-d "{\"address\": \"$ADDR\", \"blocks\": 101}"
core/.venv/bin/arrekta-wallet --seed alice.seed balanceOn the Compose devnet the admin token is in the generated .env (ARREKTA_ADMIN_TOKEN), and
node-1 already mines to the devnet miner key.
3. Send a payment with the SDK
Install the SDK (TypeScript or Python), then run the
example against your node. It builds a transaction, signs it with ML-DSA-65 and submits it to
POST /v1/txs.
/**
* Send a payment: derive a wallet, fund it on regtest, pay 1.5 ARRK, confirm.
*
* ARREKTA_URL=http://127.0.0.1:28332 ARREKTA_ADMIN_TOKEN=... npx tsx examples/send-payment.ts
*/
import { createClient, formatArrk, fromHex, generateSeed, getAddress, getChain, getCoins, keychainFromSeed, mine, sendPayment } from 'arrekta-sdk';
const URL = process.env.ARREKTA_URL ?? 'http://127.0.0.1:28332';
const ADMIN = process.env.ARREKTA_ADMIN_TOKEN; // regtest mining for the demo
const SEED = fromHex(process.env.ARREKTA_SEED ?? 'a1'.repeat(32));
// 1. Connect and read the chain.
const client = createClient({ url: URL, adminToken: ADMIN });
const chain = await getChain(client);
console.log(`connected to ${chain.network} at height ${chain.height}`);
// 2. Alice's wallet from her seed; Bob gets a fresh one.
const alice = keychainFromSeed(SEED, { network: chain.network });
const bob = keychainFromSeed(generateSeed(), { network: chain.network });
// 3. Fund Alice (regtest: mine past coinbase maturity).
if ((await getCoins(client, { wallet: alice })).length === 0) await mine(client, alice.address(0), 101);
// 4. Pay Bob 1.5 ARRK (fee rate from the node's estimate).
const sent = await sendPayment(client, { wallet: alice, to: bob.address(0), amount: '1.5' });
console.log(`sent ${sent.txid} (fee ${formatArrk(sent.fee)} ARRK)`);
// 5. Confirm and check Bob's balance.
await mine(client, alice.address(0), 1);
const balance = (await getAddress(client, { address: bob.address(0) })).balances[0]!;
console.log(`bob has ${formatArrk(balance.spendable)} ARRK`);"""Send a payment: derive a wallet, fund it on regtest, pay 1.5 ARRK, confirm.
ARREKTA_URL=http://127.0.0.1:28332 ARREKTA_ADMIN_TOKEN=... python examples/send_payment.py
"""
import os
from arrekta_sdk import Client, format_arrk, generate_seed, keychain_from_seed
URL = os.environ.get("ARREKTA_URL", "http://127.0.0.1:28332")
ADMIN = os.environ.get("ARREKTA_ADMIN_TOKEN") # regtest mining for the demo
SEED = bytes.fromhex(os.environ.get("ARREKTA_SEED", "a1" * 32))
def main() -> None:
# 1. Connect and read the chain.
client = Client(URL, admin_token=ADMIN)
chain = client.get_chain()
print(f"connected to {chain['network']} at height {chain['height']}")
# 2. Alice's wallet from her seed; Bob gets a fresh one.
alice = keychain_from_seed(SEED, network=chain["network"])
bob = keychain_from_seed(generate_seed(), network=chain["network"])
# 3. Fund Alice (regtest: mine past coinbase maturity).
if not client.get_coins(alice):
client.mine(alice.address(0), 101)
# 4. Pay Bob 1.5 ARRK (fee rate from the node's estimate).
sent = client.send_payment(alice, bob.address(0), "1.5")
print(f"sent {sent.txid} (fee {format_arrk(sent.fee)} ARRK)")
# 5. Confirm and check Bob's balance.
client.mine(alice.address(0), 1)
balance = client.get_address(bob.address(0))["balances"][0]
print(f"bob has {format_arrk(balance['spendable'])} ARRK")
if __name__ == "__main__":
main()Source: sdk/typescript/examples/send-payment.ts (updated 2026-11-02) · sdk/python/examples/send_payment.py (updated 2026-11-02). Runnable against a regtest node; CI runs every example.
Mine one more block to confirm it, then look it up:
curl -s http://127.0.0.1:28332/v1/txs/<txid>Next steps
- Learn the model: UTXO & native assets, Locks & policy locks.
- Issue your own asset: Issue an asset.
- Browse the REST API reference.