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.
- 🔗 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
# Clone the repository
git clone <repository-url>
cd rujira-bot
# Install dependencies
pnpm install
# Copy environment template
cp .env.example .envEdit 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.comimport { 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);
}The library provides simple contract access with TypeScript autocomplete. No complex registry needed!
import { trade } from "rujira-bot";
// Available contracts (you get autocomplete!)
trade["rune-usdc"] // thor1y8g3yhzmnwyt6g7jque36eyregf85kgtzem6dgzqxuzrpmzpumvqts7ud7
trade["tcy-usdc"] // thor1kyjky2yprmamj0gfkevyc6tunxev0054gpxjap8k9vkyutkkf5lqyr0xxv
trade["tcy-rune"] // thor12ds7fxj5g47jwzfzvzzhzxxd3cp6v55flgwxva0803r8k5mzm44skth6waimport { 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: {} }
});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: {} }
});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();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"]);// 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();// 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();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: {} }
});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);
}
}# Build the project
pnpm build
# Run examples
pnpm dev
# Type checking
pnpm typecheck
# Linting
pnpm lintThe 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.
See the examples/ directory for comprehensive usage examples:
# Run all examples
tsx examples/usage-examples.ts- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
- Never commit your
.envfile with real mnemonics - Use stagenet for testing and development
- Validate all transaction parameters before execution
- Keep your mnemonic phrase secure and private
MIT License - see LICENSE file for details
- 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