dvf-client-js
v3.1.4
Published
<img src="https://avatars1.githubusercontent.com/u/56512535?s=200&v=4" align="right" />
Downloads
33
Readme
Deversifi Javascript Trading API
A js client library for DeversiFi - StarkWare orders
Note: This library is for DeversiFi. A test version of the platform to use during integrations is connected to the Ropsten test network at https://app.stg.deversifi.com // https://api.stg.deversifi.com
Contents
- Installation
- Setup
- API Authentication
- Registering
- Approving tokens
- Depositing tokens
- Placing an order
- Withdrawing tokens
- Cancelling Orders
- Authenticated data endpoints
- More examples
- Troubleshooting
- Developing
- Useful Links
- Developing
Installation
NPM
npm i dvf-client-js
Prebuild for browser
Alternatively on the browser you can use the standalone build
<script src="http://path/to/dist/dvf.js"></script>
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
Instancing
Using MetaMask or a local node
// In case of MetaMask make sure you call ethereum.enable() before using it
const DVF = require('dvf-client-js')
const dvf = await DVF()
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)
dvf = await DVF(web3)
View the full example: /examples/node_sell_eth_infura.js
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 DVF function.
Parameters
api
string? (defaulthttps://api.stg.deversifi.com
) API endpoint you are connecting to Staging (ropsten): https://api.stg.deversifi.com, Production (mainnet): https://api.deversifi.com)gasApi
string? (defaulthttps://ethgasstation.info
)defaultGasLimit
number? (default200000
)defaultGasPrice
number? (default50000000000
)defaultStarkExpiry
number? (default720
) Expiration time for transfers and orders in hoursdefaultNonceAge
number? (default43200
) Nonce age in secondsdefaultProvider
string? (defaulthttp://localhost:8545
) In case no web3 provider is provided we will try connecting to this defaultautoLoadUserConf
boolean? - Enables integrators to select if they want to callgetUserConfig
upon initializationautoLoadExchangeConf
boolean? - Enables integrators to select if they want to callgetConfig
upon initialization
For instance:
dvf = await DVF(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:
{
"DVF":{
"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 dvf.config
, for instance:
const dvf = await DVF()
const config = dvf.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 Deversifi 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 dvf.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
Objectx
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 indvf.config.tokenRegistry
Returns Promise<PromiEvent>
const token = 'ETH'
await dvf.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 indvf.config.tokenRegistry
to be depositedamount
number || string Amount of tokens to be depositedstarkPrivateKey
string Trading keynonce
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 dvf.deposit(token, amount, tradingKey)
Placing an order
This authenticated endpoint is used to place an order.
Parameters
symbol
string Pair which you wish to tradeamount
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 ledgerisPostOnly
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 hoursfeeRate
number? Fee rate if knowncid
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 withcid = AAA
, but the same user cannot have two orders with the samecid
). See examplegid
string?partnerId
string?ethAddress
string?type
string? Order type (EXCHANGE LIMIT
,EXCHANGE MARKET
)protocol
string? (defaultstark
)
Returns Promise<SubmitOrderResponse>
const symbol = 'NEC:ETH'
const amount = -15
const price = 0.0025
const orderId = await dvf.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 ordernonce
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 samecid
.
Returns Promise<CancelOrderResponse>
const orderID = '123'
const customID = 'cid-123'
const order = await dvf.getOrder({ orderId: orderID })
// or
const order = await dvf.getOrder({ cid: customID })
Cancelling Orders
This method allows you to cancel a specific order by orderId
or cid
.
Parameters
orderId
string ID of the ordernonce
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 samecid
.
Returns Promise<CancelOrderResponse>
const orderID = '123'
const customID = 'cid-123'
const response = await dvf.cancelOrder({ orderId: orderID })
// or
const response = await dvf.cancelOrder({ cid: customID })
Withdrawing tokens
Requesting a withdrawal
This method submits a request for a new withdrawal.
Parameters
recipientEthAddress
string Trading keytoken
string Token symbol available indvf.config.tokenRegistry
to be withdrawnamount
number || string Amount of tokens to be withdrawn
Returns Promise<WithdrawResponse>
const token = 'ETH'
const amount = 100
const withdrawal = await await dvf.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 indvf.config.tokenRegistry
to be withdrawn
Returns Promise<{ transactionHash: string }>
const token = 'ETH'
const txHash = await dvf.withdrawOnchain(token)
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 dvf.getOrders()
// Get all historical orders
const historicalOrders = await dvf.getOrdersHist()
// Get specific order
const id = "123"
const order = await dvf.getOrder(id)
// Get exchange balances
const balance = await dvf.getBalance()
// Get deposits
const deposits = await dvf.getDeposits()
// Get withdrawals
const withdrawals = await dvf.getWithdrawals()
// Get user config
const userConfig = await dvf.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 dvf = await DVF()
dvf.set('defaultGasPrice', web3.utils.toWei('2', 'gwei'))
DVF Client 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 dvf.recommendedGasPrices
.
To configure your api key with dvf client please pass this as a userConf
parameter when initialising DVF:
javascript
dvf = await DVF(web3, {
gasStationApiKey: 'a1b2c3...'
})
or by setting the 'gasStationApiKey' property:
dvf.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 dvf.submitOrder({
symbol,
amount,
price,
cid: customOrderID,
})
// ...
// Later we can use `cid` to get order
const order = await dvf.getOrder({cid: customOrderID})
// or cancel it
await dvf.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
git clone
npm install
Implementing a new feature
Starting by watching the test files ( you will need a node running )
$ npm run test:watch
- Write the tests for your new features on the
./test/
- Add your tests to './test/index.js' file if necessary
- Create your features on ./src/ folder
- You will need a ropsten node to do blockchain related tests
Testing
On node.js
$ npm run test
On a headless browser ( using browserify and mochify )
$ npm run test:web
Manually on your browser on a browser console
- Very useful in case you want to issue commands from Google Chrome while using MetaMask !
$ npm run build:web:run
- Open your browser on http://localhost:2222
Building for browsers
- This will build the whole library as one big ugly standalone js file ( uses browserify )
$ npm run build
License
MIT