Skip to content

jpKuji/thorchain-bot

Repository files navigation

Rujira Bot - THORChain Integration Library

A TypeScript library for querying and executing transactions on the THORChain blockchain. Designed for developers who want to integrate THORChain functionality without deep blockchain expertise.

Features

  • 🔗 Multi-Network Support: Switch between THORChain mainnet and stagenet
  • 🏦 Bank Queries: Query balances and token supplies
  • 📜 Smart Contract Integration: Query and execute CosmWasm contracts
  • 📋 Contract Registry: Manage contracts with friendly names and labels
  • 🌐 THORNode API: Access native THORChain data (pools, nodes, constants)
  • 📊 Midgard API: Historical data and analytics
  • 💸 Transaction Execution: Send tokens and execute contracts with detailed responses
  • 🛡️ Comprehensive Error Handling: Detailed error messages and types
  • ⚙️ Environment Configuration: Easy setup via .env files

Installation

# Clone the repository
git clone <repository-url>
cd rujira-bot

# Install dependencies
pnpm install

# Copy environment template
cp .env.example .env

Configuration

Edit your .env file with your settings:

# Network Selection
THORCHAIN_NETWORK=stagenet  # or "mainnet"

# Wallet Configuration
MNEMONIC=your twelve or twenty four word mnemonic phrase goes here

# Contract Registry - Add your contract addresses
CONTRACT_TRADE_BTC_USDC=thor1your_btc_usdc_trade_contract_address
CONTRACT_INDEX_DEFI=thor1your_defi_index_contract_address

# Optional: Custom endpoints (will use defaults if not specified)
# CUSTOM_RPC_ENDPOINT=https://your-custom-rpc.com
# CUSTOM_THORNODE_API=https://your-custom-thornode.com
# CUSTOM_MIDGARD_API=https://your-custom-midgard.com

Quick Start

import { querySmartContract, trade, getRuneBalance, sendTokens } from "rujira-bot";

async function example() {
  // Query wallet balance
  const balance = await getRuneBalance();
  console.log("RUNE balance:", balance);

  // Query smart contract with simple contract access
  const result = await querySmartContract({
    contractAddress: trade["rune-usdc"], // TypeScript autocomplete!
    queryMsg: { book: { limit: 10 } }
  });
  console.log("Market book:", result);

  // Send tokens
  const txResult = await sendTokens({
    recipient: "thor1recipient...",
    amount: [{ denom: "rune", amount: "1000000000" }], // 1000 RUNE
    memo: "Payment"
  });
  
  console.log("Transaction hash:", txResult.txHash);
}

Contract Access

The library provides simple contract access with TypeScript autocomplete. No complex registry needed!

Simple Contract Objects

import { trade } from "rujira-bot";

// Available contracts (you get autocomplete!)
trade["rune-usdc"]  // thor1y8g3yhzmnwyt6g7jque36eyregf85kgtzem6dgzqxuzrpmzpumvqts7ud7
trade["tcy-usdc"]   // thor1kyjky2yprmamj0gfkevyc6tunxev0054gpxjap8k9vkyutkkf5lqyr0xxv
trade["tcy-rune"]   // thor12ds7fxj5g47jwzfzvzzhzxxd3cp6v55flgwxva0803r8k5mzm44skth6wa

Using Contracts

import { querySmartContract, trade } from "rujira-bot";

// Query using trade object (TypeScript autocomplete!)
const result = await querySmartContract({
  contractAddress: trade["rune-usdc"],
  queryMsg: { book: { limit: 10 } }
});

// Or use direct addresses
const directResult = await querySmartContract({
  contractAddress: "thor1direct_contract_address...",
  queryMsg: { balance: {} }
});

Adding Your Own Contracts

Simply import from the contracts directory:

// From contracts/mainnet/trade.ts
import { tradeContracts } from "../contracts/mainnet";

const result = await querySmartContract({
  contractAddress: tradeContracts.runeUsdc, // Autocomplete works here too!
  queryMsg: { book: {} }
});

API Reference

Bank Queries

import { getAllBalances, getBalance, getRuneBalance, getTotalSupply } from "rujira-bot";

// Get all balances for an address
const balances = await getAllBalances(address?);

// Get specific token balance
const balance = await getBalance("rune", address?);

// Get RUNE balance (shorthand)
const runeBalance = await getRuneBalance(address?);

// Query total supply
const totalSupply = await getTotalSupply();

Smart Contract Queries

import { querySmartContract, queryContractInfo, trade } from "rujira-bot";

// Query smart contract
const result = await querySmartContract({
  contractAddress: trade["rune-usdc"],
  queryMsg: { book: { limit: 10 } }
});

// Get contract info
const info = await queryContractInfo(trade["tcy-usdc"]);

THORNode Queries

// Network constants
const constants = await RujiraBot.getConstants();

// Mimir values
const mimir = await RujiraBot.getMimir();

// Pool information
const pool = await RujiraBot.getPool("BTC.BTC");
const allPools = await RujiraBot.getPools();

// Node information
const nodes = await RujiraBot.getNodes();
const node = await RujiraBot.getNode("thor1nodeaddress...");

// Network stats
const network = await RujiraBot.getNetwork();
const version = await RujiraBot.getVersion();

Midgard API

// Health check
const health = await RujiraBot.getHealth();

// Pool data
const pools = await RujiraBot.getPools();
const poolDetails = await RujiraBot.getPoolDetails("BTC.BTC");

// Historical data
const swaps = await RujiraBot.getSwaps({ 
  interval: "day", 
  count: 30 
});

// Member information
const members = await RujiraBot.getMembers();
const memberDetails = await RujiraBot.getMemberDetails("thor1...");

// Network statistics
const networkStats = await RujiraBot.getNetworkStats();

Transaction Execution

import { sendTokens, executeContract, estimateGas, trade } from "rujira-bot";

// Send tokens
const result = await sendTokens({
  recipient: "thor1recipient...",
  amount: [{ denom: "rune", amount: "1000000000" }],
  memo: "Payment"
});

// Execute smart contract
const result = await executeContract({
  contractAddress: trade["rune-usdc"],
  executeMsg: { 
    swap: { 
      offer_asset: { amount: "1000000", info: { native_token: { denom: "rune" } } }
    } 
  },
  funds: [{ denom: "rune", amount: "1000000" }]
});

// Estimate gas
const gasNeeded = await estimateGas({
  contractAddress: trade["tcy-usdc"],
  executeMsg: { book: {} }
});

Error Handling

The library provides specific error types for different operations:

import { 
  BankQueryError, 
  WasmQueryError, 
  TransactionError,
  ThorNodeQueryError,
  MidgardApiError,
  getBalance
} from "rujira-bot";

try {
  const balance = await getBalance("invalid-denom");
} catch (error) {
  if (error instanceof BankQueryError) {
    console.log("Bank query failed:", error.message);
  }
}

Development

# Build the project
pnpm build

# Run examples
pnpm dev

# Type checking
pnpm typecheck

# Linting
pnpm lint

Network Configuration

The library supports both THORChain networks:

  • Mainnet (thorchain-mainnet-v1): Production network with real assets
  • Stagenet (thorchain-stagenet-v2): Testing network mirroring mainnet

Switch networks by changing THORCHAIN_NETWORK in your .env file.

Examples

See the examples/ directory for comprehensive usage examples:

# Run all examples
tsx examples/usage-examples.ts

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Security

  • Never commit your .env file with real mnemonics
  • Use stagenet for testing and development
  • Validate all transaction parameters before execution
  • Keep your mnemonic phrase secure and private

License

MIT License - see LICENSE file for details

Support

  • Create an issue for bugs or feature requests
  • Check existing issues before creating new ones
  • Provide detailed information when reporting issues

Built with ❤️ for the THORChain ecosystem

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors