thru-cli 0.1.22

Command-line interface for the Thru blockchain
thru-cli-0.1.22 is not a library.

Thru CLI

A command-line interface for interacting with the Thru blockchain network. The Thru CLI provides access to RPC methods and program upload functionality, making it easy to query blockchain data and deploy programs.

Table of Contents

Installation

From Source

# Clone the repository
git clone https://github.com/thru-network/thru-rpc.git
cd thru-rpc

# Build the CLI
cargo build --release --bin thru-cli

# The binary will be available at target/release/thru-cli
# Optionally, install it to your PATH
cargo install --path thru-cli

Prerequisites

  • Rust 1.70 or later
  • Access to a Thru node RPC endpoint

Quick Start

  1. First Run: On first execution, the CLI will create a default configuration file:
thru-cli getversion

This creates ~/.thru/cli/config.yaml with default settings.

  1. Configure Your Setup: Edit the configuration file to set your RPC endpoint and private key:
# Edit the config file
nano ~/.thru/cli/config.yaml
  1. Test Connection: Verify your setup by checking node health:
thru-cli gethealth

Configuration

The CLI uses a YAML configuration file located at ~/.thru/cli/config.yaml. This file is automatically created with default values on first run.

Configuration File Structure

# Thru CLI Configuration File
# This file contains settings for the Thru command-line interface

# RPC endpoint URL for connecting to the Thru node
rpc_base_url: "http://localhost:8080"

# Default private key (64-character hex string)
# WARNING: Keep this file secure and never share your private key
default_private_key: "0000000000000000000000000000000000000000000000000000000000000000"

# Public key of the uploader program
uploader_program_public_key: "taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB"

# Request timeout in seconds
timeout_seconds: 30

# Maximum number of retries for failed requests
max_retries: 3

# Optional authorization token for HTTP requests (sent as Bearer token)
# auth_token: "your-bearer-token-here"

Configuration Parameters

Parameter Description Default Required
rpc_base_url Base URL for RPC requests http://localhost:8080 Yes
default_private_key Your private key (64-char hex) All zeros (placeholder) Yes
uploader_program_public_key Uploader program public key Default uploader Yes
timeout_seconds Request timeout 30 No
max_retries Max retry attempts 3 No
auth_token Authorization token for HTTP requests None No

RPC URL and Port Handling

The CLI uses standard port handling:

  • HTTP URLs without explicit port: Default to port 80 (e.g., http://localhosthttp://localhost:80)
  • HTTPS URLs without explicit port: Default to port 443 (e.g., https://grpc.alphanet.thruput.orghttps://grpc.alphanet.thruput.org:443)
  • Explicit ports: Used exactly as specified (e.g., http://localhost:8472 uses port 8472)

Examples:

# HTTPS with standard port (recommended for production)
rpc_base_url: "https://grpc.alphanet.thruput.org:443"

# HTTPS without explicit port (defaults to 443)
rpc_base_url: "https://grpc.alphanet.thruput.org"

# HTTP with custom port (common for local development)
rpc_base_url: "http://localhost:8472"

# HTTP without explicit port (defaults to 80)
rpc_base_url: "http://localhost"

Important: Do not use angle brackets <> around URLs in the config file.

Authentication

If your Thru node requires authentication, you can configure an authorization token in your config.yaml:

# Authentication example
rpc_base_url: "https://private.thru.io"
auth_token: "your-bearer-token-here"

The auth token will be sent as a Bearer token in the Authorization header for all HTTP requests and WebSocket connections to the RPC server.

Setting Up Your Private Key

⚠️ Security Warning: Never share your private key or commit it to version control.

  1. Generate a new private key (64 hex characters):
# Example: Generate a random private key
openssl rand -hex 32
  1. Update your config file with the generated key:
default_private_key: "your_64_character_hex_private_key_here"

Commands

The CLI supports the following commands:

RPC Commands

getversion

Get version information from the Thru node.

thru-cli [--json] getversion

gethealth

Get health status of the Thru node.

thru-cli [--json] gethealth

getaccountinfo

Get detailed account information for a specific account.

thru-cli [--json] getaccountinfo <account_public_key>

getbalance

Get balance for a specific account.

thru-cli [--json] getbalance <account_public_key>

transfer

Transfer tokens between accounts.

thru-cli [--json] transfer <src> <dst> <value>

Parameters:

  • <src>: Source key name from configuration
  • <dst>: Destination (key name from config or public address in taXX format)
  • <value>: Amount to transfer (must be greater than 0)

Program Commands

program upload

Upload a program to the blockchain.

thru-cli [--json] program upload [--uploader <pubkey>] <seed> <program_file>

Parameters:

  • --uploader <pubkey>: Optional custom uploader program public key
  • <seed>: Seed string for account derivation
  • <program_file>: Path to the program binary file

program cleanup

Clean up program accounts associated with a seed.

thru-cli [--json] program cleanup [--uploader <pubkey>] <seed>

Parameters:

  • --uploader <pubkey>: Optional custom uploader program public key
  • <seed>: Seed string for account derivation

Token Commands

token

Manage token programs and operations.

thru-cli [--json] token <subcommand> [options]

Global Options

  • --json: Output results in JSON format instead of human-readable format

Usage Examples

Basic RPC Operations

Check Node Version

# Human-readable output
$ thru-cli getversion
Version Information
  Thru Node: 1.0.0
  Thru RPC: 1.0.0

# JSON output
$ thru-cli --json getversion
{
  "version": {
    "thru-node": "1.0.0",
    "thru-rpc": "1.0.0"
  }
}

Check Node Health

# Healthy node
$ thru-cli gethealth
Node is healthy

# Unhealthy node
$ thru-cli gethealth
Node is unhealthy
  Reason: Node is behind
  Slots Behind: 150

# JSON output
$ thru-cli --json gethealth
{
  "health": "ok"
}

Get Account Information

# Human-readable output
$ thru-cli getaccountinfo taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB
Account Information
  Public Key: taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB
  Balance: 1000000
  Owner: 11111111111111111111111111111111
  Data Size: 0
  Nonce: 0
  State Counter: 0
  Is Program: No

# JSON output
$ thru-cli --json getaccountinfo taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB
{
  "account_info": {
    "pubkey": "taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB",
    "balance": 1000000,
    "owner": "11111111111111111111111111111111",
    "dataSize": 0,
    "nonce": 0,
    "stateCounter": 0,
    "program": false
  }
}

Get Account Balance

# Human-readable output
$ thru-cli getbalance taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB
Account: taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB
Balance: 1000000

# JSON output
$ thru-cli --json getbalance taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB
{
  "balance": {
    "pubkey": "taAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB",
    "balance": 1000000
  }
}

Transfer Tokens

# Transfer using key names
$ thru-cli transfer alice bob 1000
Transfer Information
  Source: alice
  Destination: bob
  Value: 1000
  Signature: ts1234567890abcdef...
  Status: success
Success: Transfer completed successfully. Transaction signature: ts1234567890abcdef...

# Transfer to public address
$ thru-cli transfer alice taXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1000
Transfer Information
  Source: alice
  Destination: taXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  Value: 1000
  Signature: ts1234567890abcdef...
  Status: success
Success: Transfer completed successfully. Transaction signature: ts1234567890abcdef...

# JSON output
$ thru-cli --json transfer alice bob 1000
{
  "transfer": {
    "src": "alice",
    "dst": "bob",
    "value": 1000,
    "signature": "ts1234567890abcdef...",
    "status": "success"
  }
}

Program Operations

Upload a Program

# Upload example event emission program
$ thru-cli program create --ephemeral event tn_event_emission_program.bin
Info: Creating ephemeral managed program from file: tn_event_emission_program.bin (11429 bytes)
Info: User seed: event
...
Success: ✓ Temporary buffer account cleaned up successfully
Success: 🎉 Ephemeral managed program created successfully!
Info: Meta account: tawj43TAX-gGvprgAofnqt_FJ2Zw8vP86n-WhGFyL4qjis
Info: Program account: taWFVEPJNOTo-VTmKizwNtGi4vPaZNyhjjJZahcwFbGkwO

# Now execute transaction against just uploaded program
$ thru-cli txn execute taWFVEPJNOTo-VTmKizwNtGi4vPaZNyhjjJZahcwFbGkwO 03000000000000000100000000000000546f2062652c206f72206e6f7420746f2062653f2020202020202020202020202020202020202020202020202020202020202020202020202020202020202020
Success: Transaction executed successfully
Signature: tskn_ZeBCq7VEx6vbxGphLfp0DOZp5VTCHa-wXXRJU1jcZmsoJOPOKG54aGkI_wcRbcP8MB8RXnGsqXNdnjFM4BRwa
Slot: 33
Compute Units Consumed: 16343
State Units Consumed: 0
Execution Result: 0
VM Error: 0
User Error Code: 3
Events Count: 3
Events Size: 246
Pages Used: 2

Events:
  Event 1: call_idx=0, program_idx=1
    Event type: 1
    Data (string): "To be, or not to be?                                            "
  Event 2: call_idx=0, program_idx=1
    Event type: 1
    Data (string): "To be, or not to be?                                            "
  Event 3: call_idx=0, program_idx=1
    Event type: 1
    Data (string): "To be, or not to be?                                            "

# Upload with default uploader
$ thru-cli program upload my_program_seed ./my_program.bin
Info: Reading program file: ./my_program.bin (1024 bytes)
Info: Program hash: a1b2c3d4e5f6789...
Info: Meta account: xyz123...
Info: Buffer account: abc456...
Info: Upload will require 3 transactions (1 chunks of 1024 bytes each)
Program Upload
  Status: success
  Total Transactions: 3
  Completed: 3
  Program Size: 1024 bytes
  Meta Account: xyz123...
  Buffer Account: abc456...
Success: Program upload completed successfully

# Upload with custom uploader
$ thru-cli program upload --uploader custom_uploader_pubkey my_program_seed ./my_program.bin

# JSON output
$ thru-cli --json program upload my_program_seed ./my_program.bin
{
  "program_upload": {
    "status": "success",
    "total_transactions": 3,
    "completed_transactions": 3,
    "program_size": 1024,
    "meta_account": "xyz123...",
    "buffer_account": "abc456..."
  }
}

Clean Up Program Accounts

# Cleanup with default uploader
$ thru-cli program cleanup my_program_seed
Info: Cleaning up accounts for seed: my_program_seed
Info: Meta account: xyz123...
Info: Buffer account: abc456...
Program Cleanup
  Status: success
  Message: Program accounts cleaned up successfully
Success: Program cleanup completed successfully

# JSON output
$ thru-cli --json program cleanup my_program_seed
{
  "program_cleanup": {
    "status": "success",
    "message": "Program accounts cleaned up successfully"
  }
}

Output Formats

The CLI supports two output formats:

Human-Readable Format (Default)

  • Colored output with clear labels
  • Status indicators (green for success, red for errors)
  • Formatted information with proper indentation
  • Progress information for long operations

JSON Format (--json flag)

  • Machine-readable structured output
  • Consistent schema across all commands
  • Suitable for scripting and automation
  • Error information included in JSON structure

Error Handling

Both output formats handle errors gracefully:

# Human-readable error
$ thru-cli getaccountinfo invalid_key
Error: Validation error: Invalid public key: invalid_key

# JSON error
$ thru-cli --json getaccountinfo invalid_key
{
  "error": "Validation error: Invalid public key: invalid_key"
}

Troubleshooting

Common Issues

1. Configuration File Not Found

Problem: CLI reports config file not found. Solution: Run any command to auto-generate the default config:

thru-cli getversion

2. Connection Refused

Problem: Failed to get version: Connection refused Solution:

  • Check if your Thru node is running
  • Verify the rpc_base_url in your config file
  • Ensure the RPC port is accessible

3. Invalid Private Key

Problem: Configuration error: Invalid private key Solution:

  • Ensure your private key is exactly 64 hexadecimal characters
  • Generate a new key: openssl rand -hex 32
  • Update your config file with the new key

4. Account Not Found

Problem: Account not found for address: ... Solution:

  • Verify the account public key is correct
  • Check if the account exists on the network
  • Ensure you're connected to the correct network

5. Program File Not Found

Problem: Program file not found: ./program.bin Solution:

  • Check the file path is correct
  • Ensure the file exists and is readable
  • Use absolute path if relative path fails

6. Timeout Errors

Problem: Request timeouts during operations Solution:

  • Increase timeout_seconds in config
  • Check network connectivity
  • Verify node is responsive

Debug Information

For debugging connection issues:

# Test basic connectivity
curl http://localhost:8080/api/getversion

# Check config file location
ls -la ~/.thru/cli/config.yaml

# Validate config syntax
cat ~/.thru/cli/config.yaml

Getting Help

# Show help for main command
thru-cli --help

# Show help for program subcommands
thru-cli uploader --help

# Show help for specific subcommand
thru-cli uploader upload --help

thru-cli program --help

Show help for specific subcommand

thru-cli program upload --help


## Security Considerations

### Private Key Security

1. **File Permissions**: Ensure your config file has restricted permissions:
```bash
chmod 600 ~/.thru/cli/config.yaml
  1. Environment Variables: Consider using environment variables for sensitive data:
export THRU_PRIVATE_KEY="your_private_key_here"
  1. Version Control: Never commit your config file with real private keys:
# Add to .gitignore
echo "~/.thru/cli/config.yaml" >> .gitignore

Network Security

  1. HTTPS: Use HTTPS endpoints for production:
rpc_base_url: "https://your-node.example.com"
  1. Firewall: Ensure your RPC endpoint is properly secured
  2. Authentication: Use proper authentication if required by your node

Best Practices

  1. Separate Keys: Use different private keys for different environments
  2. Regular Rotation: Rotate private keys periodically
  3. Backup: Securely backup your private keys
  4. Monitoring: Monitor account activity for unauthorized transactions

Program Upload Security

  1. Code Review: Always review program code before upload
  2. Testing: Test programs thoroughly on testnet first
  3. Verification: Verify program hashes match expected values
  4. Access Control: Use appropriate uploader program permissions

Advanced Usage

Scripting with JSON Output

The JSON output format makes the CLI suitable for scripting:

#!/bin/bash

# Check if node is healthy
HEALTH=$(thru-cli --json gethealth | jq -r '.health')
if [ "$HEALTH" != "ok" ]; then
    echo "Node is unhealthy: $HEALTH"
    exit 1
fi

# Get account balance
BALANCE=$(thru-cli --json getbalance $ACCOUNT_KEY | jq -r '.balance.balance')
echo "Account balance: $BALANCE"

Batch Operations

# Check multiple account balances
for account in account1 account2 account3; do
    echo "Checking balance for $account"
    thru-cli --json getbalance $account
done

Configuration Management

# Backup current config
cp ~/.thru/cli/config.yaml ~/.thru/cli/config.yaml.backup

# Use different config for different networks
export THRU_CONFIG_PATH=~/.thru/cli/testnet-config.yaml

Contributing

Contributions are welcome! Please see the main repository for contribution guidelines.

License

This project is licensed under MIT OR Apache-2.0.