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]
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:
- Rhino.fi Javascript Trading API
- Contents
- Setup
- More Examples
- Troubleshooting
- Links
- Developing
- License
- An Ethereum wallet
- A web3 provider with your account or a private key
- Such as MetaMask, keystore file, hardware wallet or raw private key
// In case of MetaMask make sure you call ethereum.enable() before using it
const RhinofiClientFactory = require('@rhino.fi/client-js')
const rhinofi = await RhinofiClientFactory()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.
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.
apistring? (defaulthttps://api.stg.rhino.fi) API endpoint you are connecting to Staging (ropsten): https://api.stg.rhino.fi, Production (mainnet): https://api.rhino.fi)gasApistring? (defaulthttps://ethgasstation.info)defaultGasLimitnumber? (default200000)defaultGasPricenumber? (default50000000000)defaultStarkExpirynumber? (default720) Expiration time for transfers and orders in hoursdefaultNonceAgenumber? (default43200) Nonce age in secondsdefaultProviderstring? (defaulthttp://localhost:8545) In case no web3 provider is provided we will try connecting to this defaultautoLoadUserConfboolean? - Enables integrators to select if they want to callgetUserConfigupon initializationautoLoadExchangeConfboolean? - Enables integrators to select if they want to callgetConfigupon 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.configAuthentication 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.
noncestring Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring The signature obtained by signing the nonce with your private ethereum key.
const nonce = (Date.now() / 1000).toString()
const signature = await rhinofi.sign(nonce)This method is used to register a stark public key that corresponds to an Ethereum public address or a trading key.
starkPublicKeyObjectxstring - First 32 bits of stark public key
noncestring Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring The signature obtained by signing the nonce with your private ethereum key.contractWalletAddressstring? Address of the deployed contract wallet (only for contract wallet integrations)
Returns Promise<UserConfigResponse>
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.
tokenstring Token symbol that's available inrhinofi.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.
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.
tokenstring Token symbol available inrhinofi.config.tokenRegistryto be depositedamountnumber || string Amount of tokens to be depositedstarkPrivateKeystring Trading keynoncestring? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring? 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)This authenticated endpoint is used to place an order.
symbolstring Pair which you wish to tradeamountnumber || 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.pricenumber || string Order price specified in the second currency in the symbol (i.e. ZRXETH). Prices should be specified to 5 s.f. maximum.noncestring? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring? The signature obtained by signing the nonce with your private ethereum key.starkPrivateKeystring? Trading key (for keystore etc.)ledgerPathstring? Ledger derivation path if using ledgerisPostOnlyboolean? Flag to indicate if the order is post-only.isHiddenboolean? Flag to indicate if the order is hidden.validFornumber? Validation time in hoursfeeRatenumber? Fee rate if knowncidstring? 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 withcid = AAA, but the same user cannot have two orders with the samecid). See examplegidstring?partnerIdstring?ethAddressstring?typestring? Order type (EXCHANGE LIMIT,EXCHANGE MARKET)protocolstring? (defaultstark)
Returns Promise<SubmitOrderResponse>
const symbol = 'NEC:ETH'
const amount = -15
const price = 0.0025
const orderId = await rhinofi.submitOrder(symbol, amount, price)This method allows you to get a specific order by orderId or cid.
orderIdstring? ID of the ordernoncestring? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring? The signature obtained by signing the nonce with your private ethereum key.cidstring? If order was placed with custom order ID (cid) property set, it can be canceled using samecid.
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 })This method allows you to cancel a specific order by orderId or cid.
orderIdstring ID of the ordernoncestring? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring? The signature obtained by signing the nonce with your private ethereum key.cidstring? If order was placed with custom order ID (cid) property set, it can be canceled using samecid.
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 })This method submits a request for a new withdrawal.
recipientEthAddressstring Trading keytokenstring Token symbol available inrhinofi.config.tokenRegistryto be withdrawnamountnumber || 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
})This method calls the contract and withdraws the tokens to your wallet
tokenstring Token symbol available inrhinofi.config.tokenRegistryto be withdrawn
Returns Promise<{ transactionHash: string }>
const token = 'ETH'
const txHash = await rhinofi.withdrawOnchain(token, recipientEthAddress)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
noncestring? Nonce which is used to provide the time until which this nonce is valid. It is presented as seconds since epoch.signaturestring? 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()Aside from these examples, there are complete examples in the examples folder
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...')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})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].
- install nix
- enter nix shell:
$ nix-shell- install js deps
$ yarn
TODO
MIT