THORChain AMM

This is a package for interacting with THORChain protocol’s AMM (Automated Market Maker).

Automatic Market Maker API

class xchainpy2_thorchain_amm.amm.THORChainAMM(wallet: Wallet, query: THORChainQuery | None = None, dry_run: bool = False, check_balance: bool = True, check_allowance: bool = True, fee_option: FeeOption = FeeOption.FAST)

Bases: object

async add_liquidity_asset_only(amount: CryptoAmount, affiliate_address: str = '', affiliate_bps: int = 0, gas_options: GasOptions | None = None) str

Add liquidity to a pool on the asset side only.

Parameters:
  • amount – CryptoAmount of the asset to add

  • affiliate_address – Affiliate address to collect affiliate fee (optional)

  • affiliate_bps – Affiliate fee in basis points (optional; default: 0)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

String TX hash submitted to the network

Return type:

str

async add_liquidity_asset_side(amount: CryptoAmount, paired_rune_address: str, affiliate_address: str = '', affiliate_bps: int = 0, gas_options: GasOptions | None = None) str

Add liquidity to a pool on the asset side. Attention: you must also add liquidity to the Rune side (add_liquidity_rune_side); if you don’t, your funds will be stuck in the pool.

Parameters:
  • amount – Amount of the asset to add

  • paired_rune_address – Address of the paired Rune

  • affiliate_address – Affiliate address to collect affiliate fee (optional)

  • affiliate_bps – Affiliate fee in basis points (optional; default: 0)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

TX hash submitted to the network

async add_liquidity_rune_only(amount: CryptoAmount, pool: Asset | str, affiliate_address: str = '', affiliate_bps: int = 0, gas_options: GasOptions | None = None) str

Add liquidity to a pool on the Rune side only.

Parameters:
  • amount – Amount of Rune to add

  • pool – Pool name to add liquidity to

  • affiliate_address – Affiliate address to collect affiliate fee (optional)

  • affiliate_bps – Affiliate fee in basis points (optional; default: 0)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

String TX hash submitted to the network

async add_liquidity_rune_side(amount: CryptoAmount, pool: Asset | str, paired_address: str, affiliate_address: str = '', affiliate_bps: int = 0, gas_options: GasOptions | None = None) str

Add liquidity to a pool on the Rune side. Attention: you must also add liquidity to the paired asset side (add_liquidity_asset_side) to complete the liquidity addition! If you don’t, your funds will be stuck in the pool.

Parameters:
  • amount – Amount of Rune to add

  • pool – Pool name to add liquidity to

  • paired_address – Address of the paired asset

  • affiliate_address – Affiliate address to collect affiliate fee (optional)

  • affiliate_bps – Affiliate fee in basis points (optional; default: 0)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

TX hash submitted to the network

async add_liquidity_symmetric(asset_amount: ~xchainpy2_utils.amount.CryptoAmount, rune_amount: ~xchainpy2_utils.amount.CryptoAmount, affiliate_address: str = '', affiliate_bps: int = 0, gas_options: ~xchainpy2_ethereum.gas.GasOptions | None = None) -> (<class 'str'>, <class 'str'>)

Add liquidity to a pool on both sides (Rune and asset) at the same time. This is 2-step operation: first, Rune side, then asset side. Note: liquidity addition is not atomic; if one side fails, the other side will still be added. Note: this method do not guarantee that your addition is symmetric; you need to check it yourself.

Parameters:
  • asset_amount – Amount of the asset to add

  • rune_amount – Amount of Rune to add

  • affiliate_address – Affiliate address to collect affiliate fee (optional)

  • affiliate_bps – Affiliate fee in basis points (optional; default: 0)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

Tuple of TX hashes submitted to the network

async add_savers(input_amount: CryptoAmount, gas_options: GasOptions | None = None) str

Adds assets to a savers value.

Parameters:
  • input_amount – CryptoAmount to add to the savers value

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

str TX hash submitted to the network

async approve_tc_router_to_spend(amount: CryptoAmount, gas_options: GasOptions | None = None)

Approve the TC Router to spend the amount of the asset.

Parameters:
  • amount – CryptoAmount to approve

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

str TX hash submitted to the network

async close()

Close the wallet and connections.

Returns:

None

property default_thor_address: str

Get the default THORChain address from the wallet. :return: str address

async deposit_to_runepool(what: CryptoAmount) str

Deposit assets to the RUNEPool. Attention! After depositing, you will not be able to withdraw the deposit until the lock up period ends. See constant/Mimir: RUNEPoolDepositMaturityBlocks

Parameters:

what – CryptoAmount to deposit, Rune only

Returns:

str TX hash submitted to the network

async deposit_to_trade_account(what: CryptoAmount, target_thor_address: str | None = None, gas_options: GasOptions | None = None) str

Deposit assets to the trade account. Trade Accounts provide professional traders (mostly arbitrage bots) a method to execute instant trades on THORChain without involving Layer1 transactions on external blockchains. Trade Accounts create a new type of asset, backed by the network security rather than the liquidity in a pool (Synthetics), or by the RUNE asset (Derived Assets). See: https://dev.thorchain.org/concepts/trade-accounts.html

Parameters:
  • what (CryptoAmount) – CryptoAmount to deposit (it must be normal L1 asset, not synth, not rune, etc.)

  • target_thor_address (Optional[str]) – Target THORChain address that will receive the deposit of the trade asset

  • gas_options (Optional[GasOptions]) – gas options. You can set gas price explicitly or use automatic fee option

Returns:

str TX hash submitted to the network

:rtype str

async do_swap(input_amount: CryptoAmount, destination_asset: Asset | str, destination_address: str = '', tolerance_bps=500, affiliate_bps=0, affiliate_address: str = '', streaming_interval=0, streaming_quantity=0, gas_options: GasOptions | None = None, allowance_check=True) str

Do a swap using the THORChain protocol AMM. In case of EVM ERC20-like tokens, it will approve the token and then do the swap. # todo: explain the swap process better

Parameters:
  • input_amount – input amount and asset to swap

  • destination_asset – output asset to swap to

  • destination_address – destination address to send swapped asset to

  • tolerance_bps – price tolerance in basis points (0-10000), default is 500 which is 0.5%

  • affiliate_bps – affiliate fee in basis points (0-10000), default 0

  • affiliate_address – affiliate address to collect affiliate fee

  • streaming_interval – streaming interval in THORChain blocks (6 sec), 0 to disable streaming

  • streaming_quantity – sub swap quantity, 0 for automatic

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

  • allowance_check – Check allowance before swap ERC20 token, default is True

Returns:

hash of the inbound transaction (used to track transaction status)

async donate(amount: CryptoAmount, pool: Asset | str = '', gas_options: GasOptions | None = None) str

Donate some crypto to the pool. You can donate Rune or non-Rune assets. Caution! After donating, you will not be able to withdraw the donation! This is irreversible.

Parameters:
  • amount – CryptoAmount to donate

  • pool – Pool name to donate to; can be empty if you donate non-Rune assets

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

TX hash submitted to the network

async general_deposit(input_amount: CryptoAmount, to_address: str, memo: str | THORMemo, gas_options: GasOptions | None = None) str

General deposit function to deposit assets to a specific inbound address with a memo. In case of Rune, it will invoke a MsgDeposit in the THORChain. In case of other assets, it will invoke a transfer to the inbound address with the memo.

Parameters:
  • input_amount (CryptoAmount) – Input amount and asset to deposit

  • to_address (str) – Inbound address to deposit to. It can be an empty string when depositing native Thor assets.

  • memo (str or THORMemo) – Memo to include with the deposit to identify your intent

  • gas_options (Optional[GasOptions]) – gas options. You can set gas price explicitly or use automatic fee option

Returns:

str TX hash submitted to the network

async general_thorname_call(payment: CryptoAmount, thorname: str, chain: Chain = Chain.THORChain, chain_address: str = '', owner: str = '', preferred_asset: Asset | None = None, expiry_block: int | None = None)

General THORName call to register, update, or unregister a THORName.

Parameters:
  • payment – How much to pay for the THORName (normally 10 Rune one time and 1 Rune per year)

  • thorname – The THORName to register

  • chain – The chain associated with the THORName (optional)

  • chain_address – The address associated with the THORName (optional)

  • owner – The owner of the THORName; may be different from the sender (optional)

  • preferred_asset – Preferred asset associated with the THORName (optional)

  • expiry_block – Expiry block for the THORName (optional)

Returns:

str TX hash

get_track_url(tx_id) str

Get the URL to the website to track the transaction.

Parameters:

tx_id – Transaction ID

Returns:

str URL to track the transaction

static is_erc20_asset(asset: Asset) bool

Check if the asset is an ERC20-like token. Basically, it calls is_erc20_asset from xchainpy2_utils.

Parameters:

asset

Returns:

async is_tc_router_approved_to_spend(amount: CryptoAmount)

Check if the TC Router is approved to spend the amount of the asset.

Parameters:

amount – CryptoAmount to check

Returns:

True if the TC Router is approved to spend the amount

static is_thorchain_asset(asset: Asset) bool

Check if the asset is a THORChain asset. Namely, it’s either native Rune or a synthetic asset. :param asset: Asset to check :return: bool True if the asset is a THORChain asset

async open_loan(amount: CryptoAmount, target_asset: str | Asset, destination_address: str, min_out: int = 0, affiliate: str = '', affiliate_bps: int = 0, gas_options: GasOptions | None = None) str

Open a loan or add assets to an existing loan. Payload is the collateral to open the loan with. Must be L1 supported by THORChain. You deposit the collateral and receive the debt in the target asset (At least Min_out USD)

Parameters:
  • amount – Payload, collateral to open the loan with.

  • target_asset – Target debt asset identifier. Can be shortened.

  • destination_address – The destination address to send the debt to. Can use THORName.

  • min_out – Minimum debt amount, else a refund. Optional, 1e8 format.

  • affiliate – The affiliate address. The affiliate is added to the pool as an LP. Optional.

Must be THORName or THOR Address. :param affiliate_bps: The affiliate fee. Fee is allocated to the affiliate. Optional. Limited from 0 to 1000 Basis Points. :param gas_options: gas options. You can set gas price explicitly or use automatic fee option :return: str TX hash submitted to the network

async register_name(thorname: str, chain: Chain = Chain.THORChain, chain_address: str = '', owner: str = '', days: float = 365)

Register a THORName with a default expiry of one year. By default, chain and chainAddress is getting from wallet instance and is BTC.

Parameters:
  • thorname – The THORName to register

  • chain – The chain associated with the THORName (optional)

  • chain_address – The address associated with the THORName (optional)

  • owner – The owner of the THORName; may be different from the sender (optional)

  • days – Expiry date for the THORName (optional)

Returns:

str TX hash

async renew_name(thorname: str, days: float, thor_address: str = '') str

Renew a THORName.

Parameters:
  • thorname – The THORName to renew

  • days – Expiry date for the THORName

  • thor_address – The THOR address associated with the THORName, if different from the sender

Returns:

str TX hash

async repay_loan(amount: CryptoAmount, collateral_asset: str | Asset, destination_address: str, min_out: int = 0, gas_options: GasOptions | None = None) str

Repay the debt and receive the collateral back.

Parameters:
  • amount – Amount and asset to repay. Target collateral asset identifier. Can be shortened.

  • collateral_asset – The target collateral asset identifier. Can be shortened.

  • destination_address – The destination address to send the collateral to. Owner of the loan.

  • min_out – Min collateral to receive else a refund. Optional, 1e8 format. Loan needs to be fully repaid to close.

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

str TX hash submitted to the network

async set_name_alias_for_chain(thorname: str, chain: Chain, chain_address: str, owner: str = '') str

Add or update an alias for a THORName on a specific chain.

Parameters:
  • thorname – THORName to add or update an alias for

  • chain – The chain to add or update an alias for

  • chain_address – The address to add or update an alias for

  • owner – The owner of the THORName; may be different from the sender (optional)

Returns:

str TX hash

async set_preferred_asset_name(thorname: str, preferred_asset: Asset | str, chain: Chain, chain_address: str, owner: str = '') str

Set the preferred asset for a THORName.

Parameters:
  • thorname – The THORName to set the preferred asset for

  • preferred_asset – Asset to set as preferred

  • chain – Chain to set the preferred asset for

  • chain_address – Address to collect affiliate fee

  • owner – The owner of the THORName; may be different from the sender (optional)

Returns:

str hash of the transaction

tracker()

Get a transaction tracker to track the status of a swap transaction

Returns:

TransactionTracker

async unregister_name(thorname: str, chain: Chain | None = None, chain_address: str = '')

Unregister a THORName.

Parameters:
  • chain – The chain associated with the THORName (optional)

  • chain_address – The address associated with the THORName (optional)

  • thorname – The THORName to unregister

Returns:

str TX hash

static validate_thorname(name: str)

Validate a THORName. It must be between 1-30 hexadecimal characters and -_+ special characters.

Parameters:

name – THORName to validate

Returns:

bool True if the THORName is valid

async withdraw_from_runepool(bp: int, affiliate_bps=0, affiliate_address: str = '') str

Withdraw assets from the RUNEPool. Attention! After depositing, you will not be able to withdraw the deposit until the lock up period ends. See constant/Mimir: RUNEPoolDepositMaturityBlocks

Parameters:
  • bp – Basis points to withdraw (0-10000)

  • affiliate_bps – Affiliate fee in basis points (0-10000), default 0

  • affiliate_address – Affiliate address to collect affiliate fee THORName or THOR address

Returns:

str TX hash submitted to the network

async withdraw_from_trade_account(what: CryptoAmount, target_l1_address: str | None = None, gas_options: GasOptions | None = None) str

Withdraw assets from the trade account. See: https://dev.thorchain.org/concepts/trade-accounts.html

Parameters:
  • what

  • target_l1_address

  • gas_options

Returns:

async withdraw_liquidity(asset: Asset | str, mode: WithdrawMode, withdraw_bps: int = 10000, gas_options: GasOptions | None = None) str

Withdraw liquidity from a pool

Parameters:
  • asset – The pool name to withdraw liquidity from

  • mode – Withdraw mode (RuneOnly, AssetOnly, Symmetric)

  • withdraw_bps – Percentage of the pool to withdraw (0-10000)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

TX hash submitted to the network

async withdraw_savers(asset: Asset | str, address: str, withdraw_bps: int, gas_options: GasOptions | None = None) str

Withdraw assets from a savers value.

Parameters:
  • asset – Asset to withdraw from the savers value

  • address – Address to withdraw to

  • withdraw_bps – Percentage of the savers value to withdraw (0-10000)

  • gas_options – gas options. You can set gas price explicitly or use automatic fee option

Returns:

str TX hash submitted to the network

AMM Models

exception xchainpy2_thorchain_amm.models.AMMException(message, errors: list | None = None)

Bases: Exception

class xchainpy2_thorchain_amm.models.ExecuteSwap(input, destination_asset, destination_address, memo, fee_option)

Bases: NamedTuple

destination_address: str | None

Alias for field number 2

destination_asset: Asset

Alias for field number 1

fee_option: FeeOption

Alias for field number 4

input: CryptoAmount

Alias for field number 0

memo: str

Alias for field number 3

exception xchainpy2_thorchain_amm.models.THORNameException(message, errors: list | None = None)

Bases: AMMException

AMM Consts

AMM Utils

xchainpy2_thorchain_amm.utils.bp_to_float(bp)

Convert basis points to float in range [0, 1] :param bp: Basis points (int or str), 0..THOR_BASIS_POINT_MAX :return: float

xchainpy2_thorchain_amm.utils.bp_to_percent(bp)

Convert basis points to percentage in range [0, 100] :param bp: Basis points (int or str), 0..THOR_BASIS_POINT_MAX :return: Percentage (float 0..100%)

xchainpy2_thorchain_amm.utils.float_to_thor(x: float) int
xchainpy2_thorchain_amm.utils.is_erc20_asset(asset: Asset)

Naive check if the asset is an ERC20 asset. Basically, the asset is an ERC20 asset if its chain is recognized as an EVM chain, and it is not a gas asset. :param asset: Asset to check :return: bool

xchainpy2_thorchain_amm.utils.thor_to_float(x) float

EVM Helper (THORChain router)

class xchainpy2_thorchain_amm.evm_helper.EVMHelper(evm_client: EthereumClient, tc_cache: THORChainCache)

Bases: object

EVMHelper is a helper class for EVM clients (e.g. EthereumClient, BinanceSmartChainClient) that provides methods to interact with THORChain router contract and manage ERC20 token allowance.

async approve_tc_router(amount: CryptoAmount, gas: GasOptions) str

Approve THORChain router to spend the asset :param amount: amount and asset you want to deposit :param gas: gas options :return: str (submitted transaction hash)

property chain: Chain

Get the chain of the EVM client

Returns:

Chain

async deposit(amount: CryptoAmount, memo: str, gas: GasOptions, expiration_sec: int = -1, check_allowance: bool = True) str

Send deposit to THORChain router :param amount: amount and asset you want to deposit :param memo: memo contains the request details (e.g. swap details) :param gas: gas options :param expiration_sec: expiration time in seconds :param check_allowance: check if the router is approved to spend the asset :return: str (submitted transaction hash)

async deposit_unsafe(asset_contract, expiration_ts, gas: GasOptions, memo, raw_amount, router, value, vault, nonce=-1)

Deposit amount to THORChain router without any checks :param asset_contract: Asset contract address :param expiration_ts: Expiration timestamp, the transaction will be rejected if it is mined after this time :param gas: Gas options :param memo: Transaction memo that contains the request details (e.g. swap details) :param raw_amount: Amount of ERC20 token to deposit :param router: THORChain router contract address :param value: Eth Value to send with the transaction :param vault: THORChain vault address :param nonce: Transaction nonce, -1 means automatic :return:

async get_router(router_address='') Contract

Get THORChain router contract instance

Parameters:

router_address – Router contract address, if not provided it will be fetched from the TC API

Returns:

Contract of web3 library

async get_router_address() str

Get THORChain router contract address from TC API (inbound_details request)

Returns:

str (router contract address)

async is_tc_router_approved_to_spend(amount: CryptoAmount) bool

Check if THORChain router is approved to spend the asset :param amount: amount and asset you want to deposit :return: bool