Giter VIP home page Giter VIP logo

client-js's Introduction

NOTE: This open-source client will be deprecated in December 2023. If you use this client to interact with rhino.fi for any reason please join our Discord and let us know so that we can continue to ensure you are supported https://discord.com/invite/V93Bxn7hAY or email [email protected]

Rhino.fi Javascript Trading API

A js client library for Rhino.fi - StarkWare orders

Note: This library is for Rhino.fi. A test version of the platform to use during integrations is connected to the Goerli test network and hosted at:

Contents

Setup

Pre Requisites

  • An Ethereum wallet
  • A web3 provider with your account or a private key
    • Such as MetaMask, keystore file, hardware wallet or raw private key

Instatiating

Using MetaMask or a local node

// In case of MetaMask make sure you call ethereum.enable() before using it
const RhinofiClientFactory = require('@rhino.fi/client-js')
const rhinofi = await RhinofiClientFactory()

Using a private key

const HDWalletProvider = require("@truffle/hdwallet-provider");
const Web3 = require("Web3")

const privateKey = '8F085...' // Account's private key
const rpcUrl = 'https://mainnet.infura.io/v3/9e28b...'

const provider = new HDWalletProvider(privateKey, rpcUrl)
const web3 = new Web3(provider)

rhinofi = await RhinofiClientFactory(web3)

For more, see examples and their README.

Configuration

It's possible to overwrite values on the configuration on a per instance basis.

The default configuration can be overwritten with an optional parameter userConf when calling the RhinofiClientFactory function.

Parameters
  • api string? (default https://api.stg.rhino.fi) API endpoint you are connecting to Staging (ropsten): https://api.stg.rhino.fi, Production (mainnet): https://api.rhino.fi)
  • gasApi string? (default https://ethgasstation.info)
  • defaultGasLimit number? (default 200000)
  • defaultGasPrice number? (default 50000000000)
  • defaultStarkExpiry number? (default 720) Expiration time for transfers and orders in hours
  • defaultNonceAge number? (default 43200) Nonce age in seconds
  • defaultProvider string? (default http://localhost:8545) In case no web3 provider is provided we will try connecting to this default
  • autoLoadUserConf boolean? - Enables integrators to select if they want to call getUserConfig upon initialization
  • autoLoadExchangeConf boolean? - Enables integrators to select if they want to call getConfig upon initialization

For instance:

  rhinofi = await RhinofiClientFactory(web3, {
    api: 'https://your-custom-api-address',
    gasStationApiKey: 'a1b2c3...'
  })

The configuration is also merged with the configuration provided by the exchange on the HTTP endpoint /v1/trading/r/getConf which at the moment looks similar to this:

{
   "RhinofiClientFactory":{
      "defaultFeeRate":0.002,
      "deversifiAddress":"0xaf8ae6955d07776ab690e565ba6fbc79b8de3a5d",
      "starkExContractAddress":"0x5d22045DAcEAB03B158031eCB7D9d06Fad24609b",
      "withdrawalBalanceReaderContractAddress":"0x650ca2dca7e2e2c8be3bb84e0a39dd77891d4d1e",
      "exchangeSymbols":[
         "ETH:USDT",
         "MKR:ETH",
         "MKR:USDT"
      ],
      "tempStarkVaultId":1,
      "minDepositUSDT":1
   },
   "tokenRegistry":{
      "ETH":{
         "decimals":18,
         "quantization":10000000000,
         "minOrderSize":0.05,
         "starkTokenId":"0xb333e3142fe16b78628f19bb15afddaef437e72d6d7f5c6c20c6801a27fba6"
      },
      "MKR":{
         "decimals":18,
         "quantization":10000000000,
         "minOrderSize":0.025,
         "tokenAddressPerChain": {
            "ETHEREUM": "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"
         },
         "starkTokenId":"0x1a4af39d27ce2e3445ed084809e5bc36d03918df04b7e2b6ee3c769a9892600"
      }
   }
}

The complete compiled configuration is accessible through rhinofi.config, for instance:

const rhinofi = await RhinofiClientFactory()

const config = rhinofi.config

API Authentication

Authentication to make all authenticated requests is done by signing a nonce using an Ethereum private key. Signing is handled by the Rhino.fi client library if the account is available and unlocked or if the web3 provider supports it. Otherwise the message and signature need to be prepared separately.

Parameters
  • nonce string Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string The signature obtained by signing the nonce with your private ethereum key.
const nonce = (Date.now() / 1000).toString()
const signature = await rhinofi.sign(nonce)

Registering

This method is used to register a stark public key that corresponds to an Ethereum public address or a trading key.

Parameters
  • starkPublicKey Object
    • x string - First 32 bits of stark public key
  • nonce string Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string The signature obtained by signing the nonce with your private ethereum key.
  • contractWalletAddress string? Address of the deployed contract wallet (only for contract wallet integrations)

Returns Promise<UserConfigResponse>

Approving Tokens

When depositing an ERC20 Ethereum-based token for the first time from a specific account, you are required to approve it to interact with the smart contracts, this is not required for ETH.

Parameters
  • token string Token symbol that's available in rhinofi.config.tokenRegistry

Returns Promise<PromiEvent>

const token = 'ETH'
await rhinofi.contract.approve(token)

This step does not need to be repeated again, and subsequently you are required only to call the deposit function.

Depositing tokens

This method is used to deposit the tokens to the smart contract and submit a signed notification of a new deposit made to the API.

Parameters
  • token string Token symbol available in rhinofi.config.tokenRegistry to be deposited
  • amount number || string Amount of tokens to be deposited
  • starkPrivateKey string Trading key
  • nonce string? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string? The signature obtained by signing the nonce with your private ethereum key.

Returns Promise<{...PromiEvent, ...DepositResponse}>

const token = 'ETH'
const amount = 100

const deposit = await rhinofi.deposit(token, amount, tradingKey)

Placing an order

This authenticated endpoint is used to place an order.

Parameters
  • symbol string Pair which you wish to trade
  • amount number || string Order amount specified in the first currency in the symbol (i.e. ZRXETH). For a sell, amount is negative. Amount accepts either maximum 8 d.p, or as many decimals as are available on the relevant token's smart contract if it is fewer than 8.
  • price number || string Order price specified in the second currency in the symbol (i.e. ZRXETH). Prices should be specified to 5 s.f. maximum.
  • nonce string? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string? The signature obtained by signing the nonce with your private ethereum key.
  • starkPrivateKey string? Trading key (for keystore etc.)
  • ledgerPath string? Ledger derivation path if using ledger
  • isPostOnly boolean? Flag to indicate if the order is post-only.
  • isHidden boolean? Flag to indicate if the order is hidden.
  • validFor number? Validation time in hours
  • feeRate number? Fee rate if known
  • cid string? Optional custom order ID that could be set when placing order and used later to retrieve order. This ID is unique per user (user A and B can each have an order with cid = AAA, but the same user cannot have two orders with the same cid). See example
  • gid string?
  • partnerId string?
  • ethAddress string?
  • type string? Order type (EXCHANGE LIMIT, EXCHANGE MARKET)
  • protocol string? (default stark)

Returns Promise<SubmitOrderResponse>

const symbol = 'NEC:ETH'
const amount = -15
const price = 0.0025

const orderId = await rhinofi.submitOrder(symbol, amount, price)

Getting Orders

This method allows you to get a specific order by orderId or cid.

Parameters
  • orderId string? ID of the order
  • nonce string? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string? The signature obtained by signing the nonce with your private ethereum key.
  • cid string? If order was placed with custom order ID (cid) property set, it can be canceled using same cid.

Returns Promise<CancelOrderResponse>

const orderID = '123'
const customID = 'cid-123'

const order = await rhinofi.getOrder({ orderId: orderID })
// or
const order = await rhinofi.getOrder({ cid: customID })

Cancelling Orders

This method allows you to cancel a specific order by orderId or cid.

Parameters
  • orderId string ID of the order
  • nonce string? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string? The signature obtained by signing the nonce with your private ethereum key.
  • cid string? If order was placed with custom order ID (cid) property set, it can be canceled using same cid.

Returns Promise<CancelOrderResponse>

const orderID = '123'
const customID = 'cid-123'

const response = await rhinofi.cancelOrder({ orderId: orderID })
// or
const response = await rhinofi.cancelOrder({ cid: customID })

Withdrawing tokens

Requesting a withdrawal

This method submits a request for a new withdrawal.

Parameters
  • recipientEthAddress string Trading key
  • token string Token symbol available in rhinofi.config.tokenRegistry to be withdrawn
  • amount number || string Amount of tokens to be withdrawn

Returns Promise<WithdrawResponse>

const token = 'ETH'
const amount = 100
const withdrawal = await await rhinofi.transferAndWithdraw({
  recipientEthAddress: address,
  token,
  amount
})

Withdraw on chain

This method calls the contract and withdraws the tokens to your wallet

Parameters
  • token string Token symbol available in rhinofi.config.tokenRegistry to be withdrawn

Returns Promise<{ transactionHash: string }>

const token = 'ETH'
const txHash = await rhinofi.withdrawOnchain(token, recipientEthAddress)

Authenticated data endpoints

If you already have an unlocked wallet available to web3 to use for signing, you can simply get data from the API as follows:

Note: You should reuse the nonce and signature and pass them to these methods while they are valid to avoid unnecessary signing

Parameters
  • nonce string? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.
  • signature string? The signature obtained by signing the nonce with your private ethereum key.
// Get all open orders
const openOrders = await rhinofi.getOrders()

// Get all historical orders
const historicalOrders = await rhinofi.getOrdersHist()

// Get specific order
const id = "123"
const order = await rhinofi.getOrder(id)

// Get exchange balances
const balance = await rhinofi.getBalance()

// Get deposits
const deposits = await rhinofi.getDeposits()

// Get withdrawals
const withdrawals = await rhinofi.getWithdrawals()

// Get user config
const userConfig = await rhinofi.getUserConfig()

More Examples

Aside from these examples, there are complete examples in the examples folder

Gas Price

You can setup a default custom gas price by setting up the 'defaultGasPrice' property

const rhinofi = await RhinofiClientFactory()

rhinofi.set('defaultGasPrice', web3.utils.toWei('2', 'gwei'))

RhinofiClientFactory calls https://ethgasstation.info API to get the current gas prices and calculate a safe gas price for Ethereum transactions. Access to the ETH Gas Station API is free, but rate limited if you are not using an API key. If a ETH Gas Station API key is not provided then a recommended gas price is used which is available in rhinofi.recommendedGasPrices.

To configure your api key with rhinofi client please pass this as a userConf parameter when initialising RhinofiClientFactory:

javascript
  rhinofi = await RhinofiClientFactory(web3, {
    gasStationApiKey: 'a1b2c3...'
  })

or by setting the 'gasStationApiKey' property:

rhinofi.set('gasStationApiKey', 'a1b2c3...')

Custom order ID

Property cid can be used to give order custom identificator for further tracking.

const symbol = 'ETH:USDT'
const amount = -1.42
const price = 3000

const customOrderID = `short-` + Math.random().toString(36).substring(7)

await rhinofi.submitOrder({
  symbol,
  amount,
  price,
  cid: customOrderID,
})

// ...
// Later we can use `cid` to get order
const order = await rhinofi.getOrder({cid: customOrderID})

// or cancel it
await rhinofi.cancelOrder({cid: customOrderID})

Troubleshooting

A list of error codes returned by the API and reasons are available here. Some more detailed explanations can also be found in the API Documentation.

If you have suggestions to improve this guide or any of the available documentation, please raise an issue on Github, or email [email protected].

Links

Developing

Setup

  1. install nix
  2. enter nix shell:
$ nix-shell
  1. install js deps
$ yarn

Implementing a new feature and Testing

TODO

License

MIT

client-js's People

Contributors

adrian-gierakowski avatar alimeer avatar ankanik avatar arijoon avatar benudall avatar catscan-crypt avatar darcsideadmin avatar dependabot[bot] avatar dvf-ci avatar gvko avatar hems avatar indie-rok avatar jakub-musik avatar konradstrachan avatar matko95 avatar neozaru avatar nicob21 avatar plutoegg avatar rhino-ci avatar sjpbeale avatar thiagokroger avatar tommycodebox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

client-js's Issues

ReferenceError: starkPrivKey is not defined

helloπŸ€—

tried " const starkPrivKey = ethPrivKey " and got

😣 "error":"ETH_STARKKEY_NOT_MATCHED"

where can i find my starkPrivKey please πŸ˜‡ ?

tried-

const starkPrivKey = dvf.stark.createPrivateKey()

got

"ETH_STARKKEY_NOT_MATCHED"

creating a backup file in app.deversifi.com changes const starkPrivKey value

After creating the trading key backup file, this message appears:

"error":"ETH_STARKKEY_NOT_MATCHED"

Please correct me if i'm wrong but stark private key value changes to an encrypted key
that can only be decrypted by my password i gave when creating this backup.

@AliMeer in issue 86# you mentioned about this subject, that:
"retrieve the stark private key from it and add it to the config",
But this file doesn't contain any value with this parameter, and iv'e tried to pass
every value from that file and it didn't work,
if you have any example for me it would be a blessing πŸ™ thank you

17.fullWithdrawalRequest doesn't return funds to wallet.

using test net, and after a several attempts i get same result-
getting a Txn only for billing my account for that withdrawal but funds never return to my wallet.

example :
node dvf-client-js-master\examples\17.fullWithdrawalRequest.js

Full withdrawal request response -> { transactionHash:
'0x2c0f6c938dca662179f76fdf9697030be722f17bcce10c7b2105bcc08a87909e' }

Stopping provider...

is this only test net issue or something else?

ETH_STARKKEY_NOT_MATCHED ETH_STARKKEY_NOT_MATCHED ETH_STARKKEY_NOT_MATCHED

howdy,
whether I use my own Ethereum wallet private key (which is registered on the exchange) or create a private key using dvf.stark.createPrivateKey() when submitting an order, It always throws this error:

{
  statusCode: 422,
  error: 'ETH_STARKKEY_NOT_MATCHED',
  message: 'ETH_STARKKEY_NOT_MATCHED',
  type: 'DVFError',
  data: {
    ethAddress: '0x0f145**************************************60016', // censored 
    starkKey: '0611b54*************************************************************ed7ff431' // censored 
  }
}

this is my code:

//starkPrivKey = config.PRIVATE_KEY //Ethereum wallet private key
 starkPrivKey = dvf.stark.createPrivateKey()
await dvf.submitOrder({
      symbol: PAIR,
      amount,
      price,
      starkPrivateKey: starkPrivKey
    })

Any suggestion to fix this?

Typings Addition

Hi,

Can I help with adding typings to this library? It gets a lot easier to use libraries with them. This would also help with faster adoption because a lot of people prefer using TS over JS

Regards,
Vasu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.