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
- 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:
objectEVMHelper 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)
- 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