THORChain Features
THORChain provides advanced DeFi features beyond simple swaps. SwapKit includes full support for these features through the THORChain plugin.
Prerequisites
Section titled “Prerequisites”To use THORChain features, you need:
- A connected wallet with RUNE
- SwapKit initialized with the THORChain plugin (included by default)
import { createSwapKit, Chain, FeeOption } from '@swapkit/sdk';
const swapKit = createSwapKit();
// Connect wallet for THORChainawait swapKit.connectKeystore([Chain.THORChain], 'your mnemonic phrase');
Liquidity Operations
Section titled “Liquidity Operations”THORChain uses an asymmetric liquidity model where you can provide single-sided or dual-sided liquidity.
Add Liquidity
Section titled “Add Liquidity”Symmetrical Liquidity (RUNE + Asset)
Section titled “Symmetrical Liquidity (RUNE + Asset)”import { AssetValue } from '@swapkit/sdk';
// Add ETH/RUNE liquidityconst runeAmount = AssetValue.from({ asset: 'THOR.RUNE', value: 100 });const ethAmount = AssetValue.from({ asset: 'ETH.ETH', value: 0.5 });
const result = await swapKit.thorchain.addLiquidity({ baseAssetValue: runeAmount, // RUNE amount assetValue: ethAmount, // Asset amount baseAssetAddr: swapKit.getAddress(Chain.THORChain), assetAddr: swapKit.getAddress(Chain.Ethereum), mode: 'sym' // Symmetrical mode});
console.log('RUNE tx:', result.baseAssetTx);console.log('ETH tx:', result.assetTx);
Asymmetrical Liquidity (Single-Sided)
Section titled “Asymmetrical Liquidity (Single-Sided)”// Add RUNE-only liquidityconst runeOnly = await swapKit.thorchain.addLiquidity({ baseAssetValue: runeAmount, assetValue: AssetValue.from({ asset: 'BTC.BTC', value: 0 }), // Required but can be 0 baseAssetAddr: swapKit.getAddress(Chain.THORChain), mode: 'baseAsset' // Use 'baseAsset' for RUNE-only});
// Add asset-only liquidity (e.g., BTC only)const btcAmount = AssetValue.from({ asset: 'BTC.BTC', value: 0.1 });
const btcOnly = await swapKit.thorchain.addLiquidity({ baseAssetValue: AssetValue.from({ asset: 'THOR.RUNE', value: 0 }), // Required but can be 0 assetValue: btcAmount, assetAddr: swapKit.getAddress(Chain.Bitcoin), mode: 'asset' // Use 'asset' for asset-only});
Create New Liquidity Position
Section titled “Create New Liquidity Position”For creating a new liquidity position (bootstrapping a pool):
const result = await swapKit.thorchain.createLiquidity({ baseAssetValue: runeAmount, // RUNE amount assetValue: ethAmount // Asset amount});
console.log('RUNE tx:', result.baseAssetTx);console.log('Asset tx:', result.assetTx);
Add Liquidity Part
Section titled “Add Liquidity Part”For more granular control, you can add liquidity parts separately:
const poolAddress = 'BTC.BTC'; // Pool identifier
await swapKit.thorchain.addLiquidityPart({ assetValue: btcAmount, poolAddress, address: swapKit.getAddress(Chain.Bitcoin), // Optional: for symmetric deposits symmetric: true});
Withdraw Liquidity
Section titled “Withdraw Liquidity”// Withdraw 50% of liquidity positionconst withdrawTx = await swapKit.thorchain.withdraw({ assetValue: AssetValue.from({ asset: 'BTC.BTC', value: 0 }), // Pool identifier percent: 50, // Withdraw 50% from: 'sym', // From position type: 'sym' | 'baseAsset' | 'asset' to: 'sym' // To asset type: 'sym' | 'baseAsset' | 'asset'});
// Withdraw asymmetric RUNE position to symmetricconst runeToSym = await swapKit.thorchain.withdraw({ assetValue: AssetValue.from({ asset: 'ETH.ETH', value: 0 }), percent: 100, // Withdraw 100% from: 'baseAsset', // From RUNE-only position to: 'sym' // To both RUNE and ETH});
// Withdraw to specific asset onlyconst toAssetOnly = await swapKit.thorchain.withdraw({ assetValue: AssetValue.from({ asset: 'BTC.BTC', value: 0 }), percent: 25, // Withdraw 25% from: 'sym', // From symmetric position to: 'asset' // Receive BTC only});
Check Liquidity Position
Section titled “Check Liquidity Position”import { SwapKitApi } from '@swapkit/helpers/api';
const thorAddress = swapKit.getAddress(Chain.THORChain);const position = await SwapKitApi.thorchainMidgard.getLiquidityPosition(thorAddress);
// Position detailsconsole.log('Pools:', position.pools);console.log('Total value USD:', position.totalValueUSD);
THORNames
Section titled “THORNames”THORNames are human-readable aliases for wallet addresses across all supported chains.
Register THORName
Section titled “Register THORName”// Register a new THORNameconst thorname = 'myname';const years = 1; // Registration period
// Check availabilityconst details = await SwapKitApi.thorchainMidgard.getTHORNameDetails(thorname);if (details.owner) { console.log('THORName already taken'); return;}
// Calculate registration fee (1 RUNE per year + network fee)const registrationFee = AssetValue.from({ asset: 'THOR.RUNE', value: years + 0.02 // 1 RUNE/year + ~0.02 network fee});
// Register the nameconst registerTx = await swapKit.thorchain.registerName({ assetValue: registrationFee, name: thorname, chain: 'THOR', // Chain identifier for the THORName address: swapKit.getAddress(Chain.THORChain), owner: swapKit.getAddress(Chain.THORChain), // Optional: different owner preferredAsset: 'ETH.ETH' // Optional: set preferred asset});
Set Preferred Asset
Section titled “Set Preferred Asset”Configure which asset you want to receive when someone sends to your THORName:
// Set preferred asset to USDCconst preferredAsset = AssetValue.from({ asset: 'ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', value: 0});
const setPreferredTx = await swapKit.thorchain.registerPreferredAsset({ assetValue: AssetValue.from({ chain: Chain.THORChain }), // Min RUNE for tx name: thorname, ownerAddress: swapKit.getAddress(Chain.THORChain), payoutAddress: swapKit.getAddress(Chain.Ethereum) // Where to receive USDC});
Update THORName Aliases
Section titled “Update THORName Aliases”Set addresses for different chains:
// Update Bitcoin address for THORNameconst updateBtcTx = await swapKit.thorchain.registerName({ assetValue: AssetValue.from({ chain: Chain.THORChain }), // Min RUNE for tx name: thorname, chain: 'BTC', // Chain identifier address: swapKit.getAddress(Chain.Bitcoin), owner: swapKit.getAddress(Chain.THORChain)});
// Update multiple chainsconst chainMap = { [Chain.Ethereum]: 'ETH', [Chain.Bitcoin]: 'BTC', [Chain.BinanceSmartChain]: 'BSC'};
for (const [chain, chainId] of Object.entries(chainMap)) { await swapKit.thorchain.registerName({ assetValue: AssetValue.from({ chain: Chain.THORChain }), name: thorname, chain: chainId, address: swapKit.getAddress(chain as Chain), owner: swapKit.getAddress(Chain.THORChain) });}
Lookup THORName
Section titled “Lookup THORName”const thornameDetails = await SwapKitApi.thorchainMidgard.getTHORNameDetails('thorswap');
console.log('Owner:', thornameDetails.owner);console.log('Preferred asset:', thornameDetails.preferredAsset);console.log('Aliases:', thornameDetails.aliases);
// Get specific chain addressconst ethAddress = thornameDetails.aliases.find(a => a.chain === 'ETH')?.address;
Node Operations
Section titled “Node Operations”For node operators, SwapKit provides bond management functions.
Bond RUNE
Section titled “Bond RUNE”import { MemoType } from '@swapkit/sdk';
const bondAmount = AssetValue.from({ asset: 'THOR.RUNE', value: 100000 });const nodeAddress = 'thor1abc...'; // Your node address
const bondTx = await swapKit.thorchain.nodeAction({ type: MemoType.BOND, assetValue: bondAmount, address: nodeAddress});
Unbond and Leave
Section titled “Unbond and Leave”// Unbond specific amountconst unbondTx = await swapKit.thorchain.nodeAction({ type: MemoType.UNBOND, assetValue: AssetValue.from({ asset: 'THOR.RUNE', value: 50000 }), address: nodeAddress});
// Leave (unbond all)const leaveTx = await swapKit.thorchain.nodeAction({ type: MemoType.LEAVE, address: nodeAddress});
Direct Deposit
Section titled “Direct Deposit”For advanced users, deposit directly to THORChain with custom memos:
// Direct deposit with custom memoconst customDeposit = await swapKit.thorchain.deposit({ assetValue: AssetValue.from({ asset: 'BTC.BTC', value: 0.1 }), recipient: '', // Empty for THORChain protocol deposits memo: 'SWAP:ETH.ETH:thor1...' // Custom memo for any THORChain action});
// Deposit to specific poolconst poolDeposit = await swapKit.thorchain.depositToPool({ assetValue: AssetValue.from({ asset: 'ETH.ETH', value: 1 }), memo: 'ADD:ETH.ETH:thor1...', feeOptionKey: FeeOption.Fast // Optional: Average, Fast, or Fastest});
// Protocol deposit (simplified)const protocolDeposit = await swapKit.thorchain.depositToProtocol({ assetValue: AssetValue.from({ asset: 'THOR.RUNE', value: 10 }), memo: 'BOND:thor1nodeaddress...'});
Token Approvals
Section titled “Token Approvals”For EVM chains, THORChain requires token approvals before deposits:
// Check if token is approvedconst isApproved = await swapKit.thorchain.isAssetValueApproved({ assetValue: AssetValue.from({ asset: 'ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', value: 1000 })});
if (!isApproved) { // Approve token for THORChain router const approveTx = await swapKit.thorchain.approveAssetValue({ assetValue: AssetValue.from({ asset: 'ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', value: 1000 }) });
console.log('Approval tx:', approveTx);}
Maya Protocol
Section titled “Maya Protocol”Maya is a fork of THORChain with similar features. SwapKit supports Maya through the Maya plugin:
// Maya operations use the same interface// Check Maya positionsconst mayaPosition = await SwapKitApi.mayachainMidgard.getLiquidityPosition( swapKit.getAddress(Chain.Maya));
Chain Information
Section titled “Chain Information”Get inbound addresses and gas rates for any supported chain:
// Get inbound data for a specific chainconst btcInbound = await swapKit.thorchain.getInboundDataByChain(Chain.Bitcoin);
console.log('BTC vault address:', btcInbound.address);console.log('BTC router:', btcInbound.router);console.log('Gas rate:', btcInbound.gas_rate);console.log('Chain halted:', btcInbound.halted);
// Check multiple chainsconst chains = [Chain.Ethereum, Chain.Bitcoin, Chain.BinanceSmartChain];for (const chain of chains) { const inbound = await swapKit.thorchain.getInboundDataByChain(chain); if (inbound.halted) { console.log(`${chain} is currently halted`); }}
Best Practices
Section titled “Best Practices”1. Check Pool Status
Section titled “1. Check Pool Status”Before adding liquidity or making swaps:
const pools = await SwapKitApi.thorchainMidgard.getPools();const btcPool = pools.find(p => p.asset === 'BTC.BTC');
if (btcPool?.status !== 'Available') { console.log('Pool not available'); return;}
2. Calculate Slippage
Section titled “2. Calculate Slippage”For large liquidity operations:
const quote = await SwapKitApi.getSwapQuote({ sellAsset: 'THOR.RUNE', sellAmount: '1000000000000', // Large amount buyAsset: 'BTC.BTC', // ... other params});
const slippage = quote.routes[0].fees.slippage;console.log(`Slippage: ${slippage}%`);
3. Monitor Transaction Status
Section titled “3. Monitor Transaction Status”Track THORChain transactions:
const txStatus = await SwapKitApi.getTrackerDetails({ txHash: 'ABCD...', chain: 'THOR'});
if (txStatus.status === 'completed') { console.log('Transaction successful');}
API Reference Summary
Section titled “API Reference Summary”Here’s a complete list of THORChain plugin methods:
Core Methods
Section titled “Core Methods”deposit()
- Direct deposit with custom parametersdepositToPool()
- Deposit to specific pool with memodepositToProtocol()
- Simplified protocol deposits
Liquidity Methods
Section titled “Liquidity Methods”addLiquidity()
- Add symmetric or asymmetric liquidityaddLiquidityPart()
- Add liquidity with granular controlcreateLiquidity()
- Bootstrap new liquidity poolswithdraw()
- Withdraw liquidity positions
THORName Methods
Section titled “THORName Methods”registerName()
- Register or update THORNamesregisterPreferredAsset()
- Set preferred payout asset
Node Methods
Section titled “Node Methods”nodeAction()
- Bond, unbond, or leave as node operator
Token Methods (EVM)
Section titled “Token Methods (EVM)”approveAssetValue()
- Approve tokens for routerisAssetValueApproved()
- Check approval status
Utility Methods
Section titled “Utility Methods”getInboundDataByChain()
- Get vault addresses and gas ratesswap()
- Execute swaps (used internally by SwapKit)
Next Steps
Section titled “Next Steps”- Explore Cross-Chain Swaps using THORChain
- Learn about Transaction Tracking
- Read the THORChain Documentation