Skip to content
SwapKit is a powerful suite of tools for building blockchain applications.

THORChain Features

THORChain provides advanced DeFi features beyond simple swaps. SwapKit includes full support for these features through the THORChain plugin.

To use THORChain features, you need:

  1. A connected wallet with RUNE
  2. SwapKit initialized with the THORChain plugin (included by default)
// @noErrorValidation
import { createSwapKit, Chain, FeeOption } from "@swapkit/sdk";
const swapKit = createSwapKit();
await swapKit.connectKeystore([Chain.THORChain], "your mnemonic phrase");

THORChain uses an asymmetric liquidity model where you can provide single-sided or dual-sided liquidity.

// @noErrorValidation
import { 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);
// @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",
});

For creating a new liquidity position (bootstrapping a pool):

// @noErrorValidation
const result = await swapKit.thorchain.createLiquidity({
baseAssetValue: runeAmount,
assetValue: ethAmount,
});
console.log("RUNE tx:", result.baseAssetTx);
console.log("Asset tx:", result.assetTx);

For more granular control, you can add liquidity parts separately:

// @noErrorValidation
const poolAddress = "BTC.BTC";
await swapKit.thorchain.addLiquidityPart({
assetValue: btcAmount,
poolAddress,
address: swapKit.getAddress(Chain.Bitcoin),
symmetric: true,
});
// @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",
});
// @noErrorValidation
import { 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 are human-readable aliases for wallet addresses across all supported chains.

// @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",
});

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),
});

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),
});
}
// @noErrorValidation
const 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;

For node operators, SwapKit provides bond management functions.

// @noErrorValidation
import { 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,
});
// @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,
});

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...",
});

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 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)
);

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`);
}
}

Before adding liquidity or making swaps:

// @noErrorValidation
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;
}

For large liquidity operations:

// @noErrorValidation
const quote = await SwapKitApi.getSwapQuote({
sellAsset: "THOR.RUNE",
sellAmount: "1000000000000",
buyAsset: "BTC.BTC",
});
const slippage = quote.routes[0].fees.slippage;
console.log(`Slippage: ${slippage}%`);

Track THORChain transactions:

// @noErrorValidation
const txStatus = await SwapKitApi.getTrackerDetails({
txHash: "ABCD...",
chain: "THOR",
});
if (txStatus.status === "completed") {
console.log("Transaction successful");
}

Here’s a complete list of THORChain plugin methods:

  • deposit() - Direct deposit with custom parameters
  • depositToPool() - Deposit to specific pool with memo
  • depositToProtocol() - Simplified protocol deposits
  • addLiquidity() - Add symmetric or asymmetric liquidity
  • addLiquidityPart() - Add liquidity with granular control
  • createLiquidity() - Bootstrap new liquidity pools
  • withdraw() - Withdraw liquidity positions
  • registerName() - Register or update THORNames
  • registerPreferredAsset() - Set preferred payout asset
  • nodeAction() - Bond, unbond, or leave as node operator
  • approveAssetValue() - Approve tokens for router
  • isAssetValueApproved() - Check approval status
  • getInboundDataByChain() - Get vault addresses and gas rates
  • swap() - Execute swaps (used internally by SwapKit)