Advanced - Integrating SwapKit API
Unlock cross-chain swaps in your application
The best way to integrate the SwapKit API is through the SwapKit SDK. For more information about that, refer to our other guide.
If you want to integrate the API directly, this guide is for you!
In this guide we will walk you through:
Fetching a quote
Setting a token allowance (EVM only)
Performing a swap
Prerequisites
API Keys
You will first need to get a free API key. Please see the partnerships page to get in touch.
Those credentials should be added to each request to our services by adding the following to your request headers:
The production API key works for all api.thorswap.net
endpoints, while the development API key works for dev-api.thorswap.net
endpoints. Both environements point at mainnet and real assets, with the dev environement getting new feature requests shipped early for testing.
Technical requirements
The code examples in this guide are written in Typescript
To follow along with this guide, you also need to have:
npm
node
private keys for a wallet with some funds
1. Fetching a quote
The SwapKit API /quote
endpoint will return an array of quotes for a given trade, ordered by the best return amount.
For more info about the endpoint look at
Let's create a function fetchBestQuote
that will retrieve a quote from the API and pick the best route available.
This will return a quote like we have seen in Requesting a Quote. A summary of the trade will be returned, and a transaction object, only if there provided wallet addresses are able to execute the trade.
The quote response contains a lot of information, and we suggest checking out the [API reference], in order to see the full response and get the most out of your integration.
1a. Inspecting the Transaction
Within the /quote
response there is a transaction
property that can be used in order to make our swap.
The SwapKit API returns a transaction
object valid from the blockchain of the sellAsset
. For example, if the sellAsset
is BTC.BTC
the transaction
property will be a hexadecimal string of a Partially Signed Bitcoin Transaction (PSBT).
The following table shows what the transaction object is for all of the blockchains supported by SwapKit API:
Sell Asset | Buy Asset | Scenario | What is Transaction? |
---|---|---|---|
ETH.CRV | BTC.BTC | Swap In | A valid Ethereum transaction object. |
BTC.BTC / LTC.LTC / DOGE.DOGE | ETH.CRV | Swap Out | A hexadecimal string of a PSBT. |
GAIA.ATOM / THOR.RUNE / BNB.BNB | ETH.CRV | Swap Out | A Cosmos TxBody |
BCH.BCH | BTC.BTC | THORChain only | An object of |
The transaction objects different depending on the Sell Asset. It's possible to sign & send each transaction object using the core-libraries of each blockchain ecosystem:
Bitcoin / Dogecoin / Litecoin - These UTXO chains use bitcoinjs-lib.
Bitcoin Cash - This uses bitcoincashjs-lib.
Cosmos / THORChain / Binance Beacon Chain - The Cosmos based chains rely on the Cosmos Client library.
2. Set a Token Allowance (EVM only)
A token allowance is required in order to allow a third-party, in this case a smart contract, to move funds on your behalf. You allow them to move your tokens.
This step is only required if you are swapping from an EVM chain. For example, ETH.CRV -> ETH.UNI, and ETH.THOR -> BTC.BTC, etc.
In our case, we need to approve a smart contract to trade our ERC20/ARC20/BEP20 tokens for us. So we will need to approve an allowance (a specified amount) for the smart contract to move the tokens on our behalf. The /quote
response returns the contract that we have to approve in the approvalTarget
property.
The process to do this in code is as follows:
Set the approval amount to
maxApproval
or pass in a lower limit.Use
approve()
to give ourapprovalTarget
an allowance for specified amount.
2a. Connect with ARC20/BEP20/ERC20 Token's approve() method
All ARC20/BEP20/ERC20 tokens adhere to the same standard, and must implement the approve(address spender, uint256 amount) function. As mentioned above, this function sets amount
as the allowance of spender
over the caller's tokens; i.e your user's tokens. It returns a boolean value indicating whether the operation was successful.
So let's do it:
Now let's set the approval amount:
Great, we've approved our token for trading! Now let's perform the swap.
3. Execute the Swap
Now let's take a look at executing the swap, and making our trade. We'll look at a few different examples, one for each of the different type of transaction objects the SwapKit API will return.
First, let's finish off the example where the sellAsset
is an EVM chain, and make a swap from ETH.CRV -> BTC.BTC
All code examples for the swaps we will cover can be found in our Github repo.
3a. ETH.CRV -> BTC.BTC - EVM Transaction Object
As mentioned in 'Inspecting the Transaction', the transaction object returned by the SwapKit API for this scenario is a valid Ethereum transaction. We will use the web3js library to sign and broadcast the transaction from our wallet.
The transaction
for this quote will look like the following:
The transaction object includes suggested gas
(the gas limit) & gasPrice.
Now we will use the signTransaction and sendSignedTransaction methods from the web3js library.
And that's all! We have successfully made a swap from ETH.CRV to native Bitcoin 🥳
3b. BTC.BTC -> ETH.CRV - PSBT Object
As mentioned in 'Inspecting the Transaction', the transaction object returned by the SwapKit API for this scenario is a valid hexadecimal string of a Partially Signed Bitcoin Transaction (PSBT). We will use the bitcoinjs-lib library to rehydrate the object, sign, and broadcast the transaction from our Bitcoin wallet.
All code examples for the swaps we will cover can be found in our Github repo.
First, let's rehydrate the PSBT:
Now we'll use the private keys of our Bitcoin wallet to sign the PSBT. There are many methods to do this. I will create my wallets private key using ecpair and tiny-secp256k libraries.
Great! Now we have the wallet's keypair in code, we can sign the inputs for the PSBT, and finalize it!
Then we must extract the transaction object from the PSBT, and broadcast our transaction to the network.
There are different public endpoints available to broadcast your transaction to, below is a snippet using Blockchair's API
Now we have successfully broadcasted a transaction to swap native BTC on the Bitcoin network, through THORChain, to CRV on Ethereum!
3c. GAIA.ATOM -> THOR.RUNE
As mentioned in 'Inspecting the Transaction', the transaction object returned by the THORSwap API for this scenario is a Cosmos TxBody. We will use the Cosmos Client library to build the rest of the transaction, sign, and broadcast the transaction to the blockchain!
All code examples for the swaps we will cover can be found in our Github repo.
First, let's initialize the CosmosSDK, then get the private keys for our Cosmos wallet, and fetch our address.
Now we can create the AuthInfo object which is required to complete the TxBuilder.
Great! We have built the transaction builder object. Now we can sign the builder using the private key we derived previously, and broadcast the transaction to the RPC we configured when instantiating the SDK.
Whoop! Now we have successfully broadcasted a transaction from the Cosmos blockchain, swapping our ATOM, through THORChain, to RUNE.
3d. BCH.BCH -> BTC.BTC
As mentioned in 'Inspecting the Transaction', the 'transaction' object returned when BitcoinCash is the sell asset differs to other UTXO assets. The API returns an object of inputs and outputs in the transaction prop. These are used to create a Transaction Builder of the bitcoincashjs-lib.
All code examples for the swaps we will cover can be found in our Github repo.
As before, we will fetch a quote from the API, specifying our desired trade. In this example, we will be swapping 10 BCH -> BTC.
Now let's pick the inputs & outputs from the 'transaction' property. Then, using bitcoincashjs-lib & coininfo libraries, we will create an instance of the TransactionBuilder.
With the builder, now we can add the inputs & outputs, returned from the API, into the builder. Bitcoincash has 2 different address types, so in order to support both possibilities, we will be using the 'bchaddrjs' library to convert BCH addresses to the legacy format.
Now let's get the private keys for our Bitcoincash wallet, and sign the inputs of our builder, before broadcasting this transaction to the Blockchair API.
There are different public endpoints available to broadcast your transaction to, below is a snippet using Blockchair's API
Great! Now we have swapped from native BCH on the Bitcoin Cash network, to native BTC on the Bitcoin network; in a totally decentralised way, using THORChain.
Last updated