@hashflow/taker-js
v0.3.7
Published
Javascript library to facilitate interactions with Hashflow backend and smart contracts for takers
Downloads
1,393
Readme
taker-js
Typescript library which exposes the hashflow taker APIs
Initializing the API
All necessary functions are exposed through the HashflowApi
object. This API object requires the following arguments to its constructor:
- mode: The type of taker you are. Set this to
'taker'
if you are a known taker application (identified by application name) OR set it to'wallet'
if you are an individual trader (identified by wallet address). - name: Your identifier. Based on your mode (see above), this will either be a taker name (e.g.
'1inch'
) or an EVM address. - authKey: Your authentication key. These are unique keys generated by the Hashflow team during the vetting phase. If you haven't gone through this process, you can contact us on Discord.
- environment (optional): Allows specifying
'staging'
for connecting to the non-production API. By default, this is set to'production'
.
Start by importing and initializing the HashflowApi
object.
import { HashflowApi } from '@hashflow/taker-js';
const hashflow = new HashflowApi(
'wallet',
'0x123...ff', // address
'!XYZ...ABC' // auth key
);
Using the API
This API object exposes a few functions for interacting with the Hashflow backend and contracts.
Backend: getMarketMakers
, getPriceLevels
(Optional)
These two functions are optional helpers to inform the requestQuote
calls (described below). For known taker applications, we recommend using both functions. For individual traders, they may be helpful but are not required.
Getting market makers: getMarketMakers
This function returns all available market makers on a given chain. This allows taker applications to separately track pricing per market maker and request quotes for specific makers only.
The interface for this function is
async getMarketMakers(chainId: number) => string[]
Getting price levels: getPriceLevels
This function gives access to indicative pricing from each market maker. This can be used for pre-determining which quotes to request and when to do so. It is especially helpful for taker applications looking to compare prices across various venues before requesting hard quotes.
The interface for this function is
async getPriceLevels(chainId: number, marketMakers: string[]) => Record<string, PairPriceLevels[]>
The result of this function is a dictionary where the keys are market makers, and the values are PairPriceLevels
arrays for the respective market makers. These entries have the following structure:
interface PairPriceLevels {
includesFees?: boolean;
pair: {
baseTokenName: string; // short name (e.g. ETH)
quoteTokenName: string; // short name (e.g. ETH)
baseToken: string; // EVM address
quoteToken: string; // EVM address
};
levels: PriceLevel[];
}
// Individual price level ( e.g. "2.5 ETH for 2000 USDC/ETH")
interface PriceLevel {
level: string; // Level-string (e.g. "2.5" for 2.5 ETH)
price: string; // Price-string (e.g. "2000" for 2000 USDC per ETH)
}
It's important to note these levels are cumulative, with each level representing the total amount supported and the incremental price compared to the previous level. Also, the first level represents the minimum supported amount.
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 5 ETH
- The first 1.5 ETH will be sold for 3000 USDC
- The next 3.5 ETH will be sold for 2999 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.
Some other things to note about these price levels:
- One entry per pair. There will be exactly one
PairPriceLevels
object for each supported pair direction. - Values are not in decimals. The
levels
andprices
are not in decimals (e.g. 1 means 1 ETH and not 1 WEI). - 0x0...0 for native tokens. For native tokens (ETH on mainnet, AVAX on avalanche), we use
'0x0...0'
as an address.
Backend: requestQuote
This is the main function for getting signed quotes from the Hashflow backend. For taker applications, we recommend using the two functions above to determine when to request quotes and for what price.
The interface of this function is
async requestQuote(input: RfqInput) => SignedQuote
with
interface RfqInput {
chainId: number;
dstChainId?: number; // Optional - used for x-chain quotes
baseToken: string; // EVM address
quoteToken: string; // EVM address
baseTokenAmount?: string; // decimal-string for baseToken amount (e.g. '1000000' for 1 USDT)
quoteTokenAmount?: string; // exactly one of baseTokenAmount/quoteTokenAmount must be set
wallet?: string; // YOUR wallet – only specify if using 'taker' mode
effectiveTrader?: string; // TRADER wallet – only specify if using 'taker' mode
marketMakers?: string[]; // Optional - restrict to specific market makers
}
interface SignedQuote {
status: 'success' | 'fail';
rfqId: string; // Unique ID of your request for quote;
quoteData?: QuoteData; // Quote object – present if status = 'success'
signature?: string; // Quote signature
gasEstimate?: number; // Estimated number of gas units
nativeTokenPriceUsd?: number; // Current USD price of 'gas' token
}
interface QuoteData {
rfqType: 0 | 1;
txid: string; // Unique ID of quote (different from RFQ-ID)
eoa?: string;
baseToken: string;
quoteToken: string;
baseTokenAmount: string;
quoteTokenAmount: string;
quoteExpiry: number; // Timestamp when this quote will expire
fees: string;
trader: string;
effectiveTrader?: string;
pool: string; // Hashflow pool you're trading with
dstPool?: string;
nonce?: number;
}
Contracts: executeTrade
After calling requestQuote(...)
and looking at the quote price (baseTokenAmount
/ quoteTokenAmount
), you can decide to make the swap using executeTrade
. This function interacts with the blockchain and calls Hashflow's smart contracts.
The interface of this function is
async executeTrade(
signer: Signer,
chainId: number,
quoteData: QuoteData,
signature: string,
options?: Options // Optional – EVM options to use with the contract call
) => string
The return value of this function call is the transactionHash of your submitted trade. All of the input fields (except for signer
, as detailed below) can be taken from the result of calling requestQuote
.
NOTE: To call this function, you'll need to pass an ethers.Signer object to executeTrade
. This signer is then used to call the smart contract with your address and key. You should be able to find many tutorials online for creating your Signer object.