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)
// @noErrorValidationimport { createSwapKit, Chain, FeeOption } from "@swapkit/sdk";
const swapKit = createSwapKit();
await 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)”// @noErrorValidationimport { AssetValue } from "@swapkit/sdk";
const 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, assetValue: ethAmount, baseAssetAddr: swapKit.getAddress(Chain.THORChain), assetAddr: swapKit.getAddress(Chain.Ethereum), mode: "sym",});
console.log("RUNE tx:", result.baseAssetTx);console.log("ETH tx:", result.assetTx);
Asymmetrical Liquidity (Single-Sided)
Section titled “Asymmetrical Liquidity (Single-Sided)”// @noErrorValidation
const runeOnly = await swapKit.thorchain.addLiquidity({ baseAssetValue: runeAmount, assetValue: AssetValue.from({ asset: "BTC.BTC", value: 0 }), baseAssetAddr: swapKit.getAddress(Chain.THORChain), mode: "baseAsset",});
const btcAmount = AssetValue.from({ asset: "BTC.BTC", value: 0.1 });
const btcOnly = await swapKit.thorchain.addLiquidity({ baseAssetValue: AssetValue.from({ asset: "THOR.RUNE", value: 0 }), assetValue: btcAmount, assetAddr: swapKit.getAddress(Chain.Bitcoin), mode: "asset",});
Create New Liquidity Position
Section titled “Create New Liquidity Position”For creating a new liquidity position (bootstrapping a pool):
// @noErrorValidationconst result = await swapKit.thorchain.createLiquidity({ baseAssetValue: runeAmount, assetValue: ethAmount,});
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:
// @noErrorValidationconst poolAddress = "BTC.BTC";
await swapKit.thorchain.addLiquidityPart({ assetValue: btcAmount, poolAddress, address: swapKit.getAddress(Chain.Bitcoin), symmetric: true,});
Withdraw Liquidity
Section titled “Withdraw Liquidity”// @noErrorValidation
const withdrawTx = await swapKit.thorchain.withdraw({ assetValue: AssetValue.from({ asset: "BTC.BTC", value: 0 }), percent: 50, from: "sym", to: "sym",});
const runeToSym = await swapKit.thorchain.withdraw({ assetValue: AssetValue.from({ asset: "ETH.ETH", value: 0 }), percent: 100, from: "baseAsset", to: "sym",});
const toAssetOnly = await swapKit.thorchain.withdraw({ assetValue: AssetValue.from({ asset: "BTC.BTC", value: 0 }), percent: 25, from: "sym", to: "asset",});
Check Liquidity Position
Section titled “Check Liquidity Position”// @noErrorValidationimport { SwapKitApi } from "@swapkit/helpers/api";
const thorAddress = swapKit.getAddress(Chain.THORChain);const position = await SwapKitApi.thorchainMidgard.getLiquidityPosition( thorAddress);
console.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”// @noErrorValidation
const thorname = "myname";const years = 1;
const details = await SwapKitApi.thorchainMidgard.getTHORNameDetails(thorname);if (details.owner) { console.log("THORName already taken"); return;}
const registrationFee = AssetValue.from({ asset: "THOR.RUNE", value: years + 0.02,});
const registerTx = await swapKit.thorchain.registerName({ assetValue: registrationFee, name: thorname, chain: "THOR", address: swapKit.getAddress(Chain.THORChain), owner: swapKit.getAddress(Chain.THORChain), preferredAsset: "ETH.ETH",});
Set Preferred Asset
Section titled “Set Preferred Asset”Configure which asset you want to receive when someone sends to your THORName:
// @noErrorValidation
const preferredAsset = AssetValue.from({ asset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", value: 0,});
const setPreferredTx = await swapKit.thorchain.registerPreferredAsset({ assetValue: AssetValue.from({ chain: Chain.THORChain }), name: thorname, ownerAddress: swapKit.getAddress(Chain.THORChain), payoutAddress: swapKit.getAddress(Chain.Ethereum),});
Update THORName Aliases
Section titled “Update THORName Aliases”Set addresses for different chains:
// @noErrorValidation
const updateBtcTx = await swapKit.thorchain.registerName({ assetValue: AssetValue.from({ chain: Chain.THORChain }), name: thorname, chain: "BTC", address: swapKit.getAddress(Chain.Bitcoin), owner: swapKit.getAddress(Chain.THORChain),});
const 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”// @noErrorValidationconst thornameDetails = await SwapKitApi.thorchainMidgard.getTHORNameDetails( "thorswap");
console.log("Owner:", thornameDetails.owner);console.log("Preferred asset:", thornameDetails.preferredAsset);console.log("Aliases:", thornameDetails.aliases);
const 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”// @noErrorValidationimport { MemoType } from "@swapkit/sdk";
const bondAmount = AssetValue.from({ asset: "THOR.RUNE", value: 100000 });const nodeAddress = "thor1abc...";
const bondTx = await swapKit.thorchain.nodeAction({ type: MemoType.BOND, assetValue: bondAmount, address: nodeAddress,});
Unbond and Leave
Section titled “Unbond and Leave”// @noErrorValidation
const unbondTx = await swapKit.thorchain.nodeAction({ type: MemoType.UNBOND, assetValue: AssetValue.from({ asset: "THOR.RUNE", value: 50000 }), address: nodeAddress,});
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:
// @noErrorValidation
const customDeposit = await swapKit.thorchain.deposit({ assetValue: AssetValue.from({ asset: "BTC.BTC", value: 0.1 }), recipient: "", memo: "SWAP:ETH.ETH:thor1...",});
const poolDeposit = await swapKit.thorchain.depositToPool({ assetValue: AssetValue.from({ asset: "ETH.ETH", value: 1 }), memo: "ADD:ETH.ETH:thor1...", feeOptionKey: FeeOption.Fast,});
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:
// @noErrorValidation
const isApproved = await swapKit.thorchain.isAssetValueApproved({ assetValue: AssetValue.from({ asset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", value: 1000, }),});
if (!isApproved) { 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:
// @noErrorValidation
const 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:
// @noErrorValidation
const 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);
const 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:
// @noErrorValidationconst 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:
// @noErrorValidationconst quote = await SwapKitApi.getSwapQuote({ sellAsset: "THOR.RUNE", sellAmount: "1000000000000", buyAsset: "BTC.BTC",});
const slippage = quote.routes[0].fees.slippage;console.log(`Slippage: ${slippage}%`);
3. Monitor Transaction Status
Section titled “3. Monitor Transaction Status”Track THORChain transactions:
// @noErrorValidationconst 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](https: