Getting Started - API v3
Taker API V3 is a REST API, similar to Taker API V2.
This section will walk you through the required steps to add Hashflow as a liquidity source for your platform. This could be an aggregator, an algorithmic trading bot, or any software intended to run trades against Hashflow liquidity.
1. Set up authentication
Hashflow authenticates all incoming requests based on the source
field (passed in the requests below). This helps us track usage, as well as prevent DDoS attacks.
The first step in setting up your taker is reaching out to the Hashflow team, in order to have credentials generated. Depending on the type of taker, the team will provide you with different types of credentials.
A. Aggregators / API Multi-Wallet Traders
This type of API integration is viable for takers such as aggregators (e.g. 1inch
, paraswap
). The team will provide you with two important pieces of information:
your
source
namethe authentication key for your
source
B. API Wallet Traders
This type of API integration is viable for individual takers that generally rely on one or very few wallets (e.g. retail traders, funds).
The team will provide you with an authentication key that is bound to the wallet you will be using to access the API.
Authenticating requests
Regardless of the integration type, you have to submit a header with each request:
Authorization: <generated credential key>
This, in conjunction with your identity parameters, will authenticate your request. For identity, parameters, the type of integration matters.
A. Aggregators / API Multi-Wallet Traders
You will have to provide the source
field to every request (GET
or POST
).
B. API Wallet Traders
You will have to set source: 'api'
to every request, and also send a field named wallet
which is populated with your wallet address (e.g. 0x01ae...b3
).
2. Query /market-makers
/market-makers
Next, you will need to query which market makers (liquidity sources) are currently available on Hashflow for a given network. You can do this by sending the following HTTP REST request:
OR, for single wallet traders
For
<source>
use your source identifier (e.g.my_aggregator
) orapi
For
<baseChainType>
use eitherevm | solana
For
<baseChainId>
use your network ID (e.g.1
for Ethereum,137
for Polygon,1000001
for Solana).For
<wallet>
use the0x
-prefixed wallet address (only populate when you are single wallet traders)Make sure you also use the header that authenticates your source
The response to this request includes all available market makers on that chain and has format
For example: {marketMakers: ['mm1', 'mm2']}
.
You'll want to re-run this request periodically for each chain so that you can tell which market makers are available.
3. Query Price Levels (for price discovery)
In order to understand indicative order flow, we expose price levels for the different market makers. These levels tell you, at any given time:
what pairs are available for a given network (chain)
how much liquidity is available for each particular pair
what the rough prices will be once you query signed quotes for those pairs
In general, this step will allow you to do price discovery (which is inexpensive), before requesting signed quotes (which is more expensive).
The price levels APIs benefit from caching and can be queried frequently (e.g. every second).
You can get those by querying:
OR, for single wallet traders
This endpoint allows you query levels for an arbitrary number of market makers.
You will then get a response of the following format:
Things to note:
for each market maker, there will be one entry in the top level array for each supported pair
levels and prices are not in decimals (e.g. 1 means 1 ETH and not 1 WEI)
for native tokens (e.g. AVAX on avalanche, ETH on ethereum) Hashflow uses the 0 address (
0x00..00
)
Each level represents up to how much liquidity can be accessed at a given price. Also, the first level represents the minimum amount that the market maker is willing to take a quote for.
For example, suppose our levels for ETH-USDC
are
{ level: "0.5", "price": "3000" }
{ level: "1.5", price: "3000"}
{ level: "5", price: "2999"}
This tells us the following:
the trader needs to sell at least
0.5 ETH
the trader can sell up to
7 ETH
the first
2 ETH
will be sold at a price of3000 USDC
the next
5 ETH
will be sold at a price2999 USDC
For example, if the trader wants to sell 3 ETH
they will get 2 * 3000 + 2999 = 8999 USDC
Note that, in general, as liquidity goes up, rates go down. This is expected, as market maker prices generally mirror Centralized Exchange order books.
Cross-Chain price levels
In order to get cross-chain price levels, simply add quoteChainType, quoteChainId
as a parameter, indicating the destination Chain ID and type for the cross-chain trade.
For example:
4. Query /rfq
/rfq
By this point, you should have an index of what market makers are available on each chain and which trading pairs they offer, as well as prices they are offering. The next step is to request a signed quote that is ready for execution.
This can target specific market makers, or be sent to all available market makers.
This request will look like:
When provide marketMakers
field, to provide better success rate, we by default will route your RFQ to other makers provide liquidity for the same maker if your specified maker failed the initial request. If you do NOT want us to re-route your RFQ to other available maker instead return failed request, please set doNotRetryWithOtherMakers
to true
in side options
when you send RFQ request.
If you're a Wallet API trader, the trader
field will be used in lieu of the wallet
field, which does not need to be passed. However, you still need to pass source:api
in order to avoid rate limits.
You will then get a response of the following format:
5. Execute quote on-chain
Once you have obtained a signed quote and decided to execute it, you can submit it on-chain to the HashflowRouter
contract via the tradeRFQT
call.
The call is meant to be composable. However, since it is most often composed with AMMs that have slippage, the Hashflow contracts allow you to tune the token amounts in order to account for slippage (see the description of maxBaseTokenAmount
below).
HashflowRouter
Contract: https://github.com/hashflownetwork/x-protocol/blob/main/evm/deployed-contracts/IHashflowRouter.json
ABIs: https://github.com/hashflownetwork/x-protocol/blob/main/evm/abi/IHashflowRouter.json
Some clarification for the ABI fields:
externalAccount
. External account address. Set toeoa
, if set in your signed quote. Otherwise, use0x0000000000000000000000000000000000000000
address.maxBaseTokenAmount
/maxQuoteTokenAmount
: These are what you receive in the API asbaseTokenAmount
/quoteTokenAmount
. Sometimes you can receive a quote for higher than what you requested. It is essential that you use the requested amount in the effectiveBaseTokenAmount field.effectiveBaseTokenAmount
: The actual swapped amount. This has to be less than or equal tomaxBaseTokenAmount
. We suggest to keep them equal unless there's a discrepancy with the requested amount. If theeffectiveBaseTokenAmount
is less thanmaxBaseTokenAmount
, the exchange ratemaxQuoteTokenAmount / maxBaseTokenAmount
will be preserved and applied toeffectiveBaseTokenAmount
value
: If the baseToken is the native token (e.g. ETH on Ethereum), theeffectiveBaseTokenAmount
needs to be passed asvalue
to the contract call
You can use Etherscan (or similar tools for non-Ethereum chains) to confirm the trade went through.
Executing cross-chain quotes
Cross-chain quotes are executed via our interoperability partner, Wormhole. Wormhole operates with 2 parties:
a set of Guardians to attest the transaction
a Relayer on the destination chain
Both of these entities could charge a small fee. However, once the transaction is submitted on the source chain, they will take care of execution on the destination chain.
Therefore, a fee has to be paid by the trader on the source chain, in the source chain's native token (e.g. ETH for Ethereum). This fee will pay for:
Guardian fees
Relayer fees
Gas fees on the destination chain
The fee that needs to be paid for each quote is returned in the rfqs
response's xChainFeeEstimate
field.
The amount provided is in WEI (decimals -- usually 10^-18
).
Once we have a quote, as well as a fee estimate, we can go ahead and submit the quote for execution via the tradeXChainRFQT
contract call.
6. Query /restrictions
/restrictions
Market makers can set rate_limit
on given a trader and a network. All rate_limit
restrictions will have an expiry window, which means traders can re-gain access to the market maker after the specified expiry time. To understand the restriction status, takers can query /restrictions
endpoint to better understand error messages from market maker and adjust routing accordingly. When a trader has been restricted, we will automatically route their RFQs to other makers (if present) until restriction expires.
We suggest you use the response you get from this endpoint to display proper error message as well as route your RFQs requests to other available makers accordingly.
For example:
The response will be in the following shape
Last updated