npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@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:

  1. 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).
  2. name: Your identifier. Based on your mode (see above), this will either be a taker name (e.g. '1inch') or an EVM address.
  3. 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.
  4. 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:

  1. The trader needs to sell at least 0.5 ETH
  2. The trader can sell up to 5 ETH
  3. The first 1.5 ETH will be sold for 3000 USDC
  4. 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:

  1. One entry per pair. There will be exactly one PairPriceLevels object for each supported pair direction.
  2. Values are not in decimals. The levels and prices are not in decimals (e.g. 1 means 1 ETH and not 1 WEI).
  3. 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.