Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@kava-labs/kava-tools

Package Overview
Dependencies
Maintainers
4
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kava-labs/kava-tools - npm Package Compare versions

Comparing version 0.2.2 to 0.4.0

docker-compose.yaml

64

oracle/oracle.js

@@ -11,3 +11,3 @@ require('dotenv').config();

class PriceOracle {
constructor(marketIDs, expiry, expiryThreshold, deviation) {
constructor(marketIDs, expiry, expiryThreshold, deviation, fee) {
if (!marketIDs) {

@@ -25,2 +25,5 @@ throw new Error('must specify at least one market ID');

}
if (!fee) {
throw new Error('must specify fee')
}

@@ -30,4 +33,4 @@ // Validate each market ID on Binance and CoinGecko

try {
utils.loadBinanceMarket(marketIDs[i]);
utils.loadCoinGeckoMarket(marketIDs[i]);
utils.loadPrimaryMarket(marketIDs[i]);
utils.loadBackupMarket(marketIDs[i]);
} catch (e) {

@@ -44,2 +47,3 @@ console.log("couldn't load remote market from market ID, error:", e);

this.deviation = deviation;
this.fee = fee
}

@@ -126,3 +130,3 @@

try {
await this.client.checkTxHash(txHash, 25000);
await this.client.checkTxHash(txHash, 120000);
} catch (e) {

@@ -133,3 +137,3 @@ checkTxError = true

try {
await this.client.checkTxHash(txHash, 25000);
await this.client.checkTxHash(txHash, 120000);
} catch (error) {

@@ -151,3 +155,3 @@ console.log(`Tx not accepted by chain: ${error}`);

try {
res = await this.fetchPriceBinance(marketID);
res = await this.fetchPrimaryPrice(marketID);
if (!res.success) {

@@ -160,4 +164,4 @@ binanceError = true

if (binanceError) {
console.log("trying coingecko after error")
res = await this.fetchPriceCoinGecko(marketID);
console.log("trying backup price source after error")
res = await this.fetchBackupPrice(marketID);
}

@@ -167,2 +171,29 @@ return res;

/**
* Fetches price from the primary source for a market
* @param {String} marketID the market's ID
*/
async fetchPrimaryPrice(marketID) {
switch (marketID) {
case 'usdx:usd':
return this.fetchPriceBitmax(marketID)
default:
return this.fetchPriceBinance(marketID)
}
}
/**
* Fetches price from the backup source for a market
* @param {String} marketID the market's ID
*/
async fetchBackupPrice(marketID) {
switch (marketID) {
case 'usdx:usd':
return this.fetchPriceBitmax(marketID)
default:
return this.fetchPriceCoinGecko(marketID)
}
}
/**

@@ -198,2 +229,17 @@ * Fetches price from Binance

/**
* Fetches price from Coin Gecko
* @param {String} marketID the market's ID
*/
async fetchPriceBitmax(marketID) {
let retreivedPrice;
try {
retreivedPrice = await prices.getBitmaxPrice(marketID);
} catch (e) {
console.log(`could not get ${marketID} price from Bitmax`);
return { price: null, success: false };
}
return { price: retreivedPrice, success: true };
}
/**

@@ -265,3 +311,3 @@ * Validates price post against expiration time and derivation threshold

);
return await this.client.postPrice(marketID, newPrice, newExpiry, undefined, sequence);
return await this.client.postPrice(marketID, newPrice, newExpiry, this.fee, sequence);
}

@@ -268,0 +314,0 @@

@@ -77,5 +77,35 @@ require('log-timestamp');

var getBitmaxPrice = async (marketID) => {
try {
var url = coinUtils.loadBitmaxQuery(marketID)
} catch (e) {
throw new Error(`could not load ${marketID} query from bitmax`)
}
try {
var priceFetch = await axios.get(url)
} catch(e) {
console.log(e)
throw new Error(`could not fetch ${marketID} price from bitmax`)
}
try {
const proposedPrice = coinUtils.postProcessBitmaxPrice(
marketID,
priceFetch.data.data
)
if (!proposedPrice) {
throw new Error(`could not post-process ${marketID} from bitmax`)
}
return proposedPrice
} catch (e) {
console.log(e)
console.log(`failure to post-process bitmax price request for ${marketID}
data: ${priceFetch.data}`)
throw new Error(`could not post-process ${marketID} price for bitmax`)
}
}
module.exports.prices = {
getBinancePrice,
getCoinGeckoPrice,
getBitmaxPrice,
};

25

oracle/README.md
# Oracle
Client software for running an oracle on the kava blockchain. Currently tested against kava-testnet-8000.
Client software for running an oracle on the kava blockchain. Currently tested against kava-testnet-11000.
## How it works
At the specified crontab frequency, the oracle client will query the Binance v3 API for price information about that asset. If Binance is down, it will fallback to CoinGecko. If the price meets the threshold for posting (default is 0.5% change from the previous posted price), is will submit a `postprice` transaction to the blockchain along with a time when that price should be considered expired. At the end of each block, the median price of all oracles is selected as the asset's current price.
## Requirements
* NodeJS - tested against version 10.x+
* npm
* yarn

@@ -19,3 +23,3 @@ ## Setup

```
npm i
yarn
```

@@ -30,3 +34,3 @@

# the chain-id
CHAIN_ID="kava-testnet-8000"
CHAIN_ID="kava-testnet-11000"

@@ -36,4 +40,4 @@ # REST endpoint

# Cron tab for how frequently prices will be posted (ex: 1 minute)
CRONTAB="* * * * *"
# Cron tab for how frequently prices will be posted (ex: 5 minutes)
CRONTAB="*/5 * * * *"

@@ -44,3 +48,3 @@ # bip39 mnemonic of oracle

# List of markets the oracle will post prices for. See pricefeed parameters for the list of active markets.
MARKET_IDS="bnb:usd,bnb:usd:30"
MARKET_IDS="bnb:usd,bnb:usd:30,btc:usd,btc:usd:30,xrp:usd,xrp:usd:30,busd:usd,busd:usd:30,kava:usd,kava:usd:30,hard:usd,hard:usd:30,usdx:usd"

@@ -59,2 +63,5 @@ # percentage deviation from previous price needed to trigger a new price - (example 0.5%)

LEGACY_HD_PATH="false"
# if the oracle should include a fee when posting prices (in integer ukava units). Example will pay 10000ukava (.01 KAVA)
FEE="10000"
```

@@ -93,5 +100,1 @@

To run the oracle from a Chainlink node, you need to configure an external adapter for interacting with kava. Instructions can be found at [chainlink-adapter-kava](https://github.com/Kava-Labs/external-adapters-js/tree/master/kava)
## How it works
At the specified crontab frequency, the oracle client will query the Binance v3 API for price information about that asset. If Binance is down, it will fallback to CoinGecko. If the price meets the threshold for posting (default is 0.5% change from the previous posted price), is will submit a `postprice` transaction to the blockchain along with a time when that price should be considered expired. At the end of each block, the median price of all oracles is selected as the asset's current price.

@@ -15,2 +15,5 @@ const util = require('util');

);
const BITMAX_V1_TICKER_REQUEST = util.format(
'https://bitmax.io/api/pro/v1/ticker?symbol=%s/%s'
)

@@ -46,3 +49,3 @@ const loadCoinGeckoMarket = (marketID) => {

default:
throw `invalid market id ${marketID}`;
throw `invalid coin gecko market id ${marketID}`;
}

@@ -106,3 +109,3 @@ };

default:
throw `invalid market id ${marketID}`;
throw `invalid coingecko market id ${marketID}`;
}

@@ -137,2 +140,20 @@ };

const loadPrimaryMarket = (marketID) => {
switch (marketID) {
case 'usdx:usd':
return loadBitmaxMarket(marketID)
default:
return loadBinanceMarket(marketID)
}
}
const loadBackupMarket = (marketID) => {
switch (marketID) {
case 'usdx:usd':
return loadBitmaxMarket(marketID)
default:
return loadCoinGeckoMarket(marketID)
}
}
const loadBinanceMarket = (marketID) => {

@@ -167,6 +188,15 @@ switch (marketID) {

default:
throw `invalid market id ${marketID}`;
throw `invalid binance market id ${marketID}`;
}
};
const loadBitmaxMarket = (marketID) => {
switch (marketID) {
case 'usdx:usd':
return 'USDXUSDT';
default:
throw `invalid bitmax market id ${marketID}`
}
}
const loadBinanceQuery = (marketID) => {

@@ -201,3 +231,3 @@ switch (marketID) {

default:
throw `invalid market id ${marketID}`;
throw `invalid binance market id ${marketID}`;
}

@@ -252,2 +282,18 @@ };

const loadBitmaxQuery = (marketID) => {
switch (marketID) {
case 'usdx:usd':
return util.format(BITMAX_V1_TICKER_REQUEST, "USDX", "USDT");
default:
throw `invalid bitmax market id ${marketID}`
}
}
const postProcessBitmaxPrice = (marketID, data) => {
switch (marketID) {
default:
return data.close;
}
};
module.exports.utils = {

@@ -257,7 +303,12 @@ loadCoinGeckoMarket,

postProcessCoinGeckoPrice,
loadPrimaryMarket,
loadBackupMarket,
loadBinanceMarket,
loadBinanceQuery,
loadBitmaxMarket,
loadBitmaxQuery,
postProcessBinancePrice,
getPreviousPrice,
getPercentChange,
postProcessBitmaxPrice
};
{
"name": "@kava-labs/kava-tools",
"description": "Tools for interacting with the Kava blockchain",
"version": "0.2.2",
"version": "0.4.0",
"license": "Apache-2.0",

@@ -17,4 +17,4 @@ "main": "index.js",

"dependencies": {
"@kava-labs/javascript-sdk": "^3.0.0-beta.1",
"axios": "^0.19.2",
"@kava-labs/javascript-sdk": "^4.0.1-beta.1",
"axios": "^0.21.1",
"coingecko-api": "^1.0.10",

@@ -21,0 +21,0 @@ "dotenv": "^8.2.0",

@@ -1,2 +0,2 @@

require('dotenv').config();
require('dotenv').config({path: process.env.ENV_FILE} );
const PriceOracle = require('..').PriceOracle;

@@ -13,2 +13,4 @@ const cron = require('node-cron');

const deviation = process.env.DEVIATION;
let feeAmount = process.env.FEE;
let fee = { amount: [], gas: String(150000) }
let legacyHDPath = false

@@ -18,5 +20,8 @@ if (process.env.LEGACY_HD_PATH === 'true') {

}
if (feeAmount !== "") {
fee = { amount: [{denom: "ukava", amount: feeAmount }], gas: String(150000) }
}
// Initiate price oracle
oracle = new PriceOracle(marketIDs, expiry, expiryThreshold, deviation);
oracle = new PriceOracle(marketIDs, expiry, expiryThreshold, deviation, fee);
await oracle.initClient(lcdURL, mnemonic, legacyHDPath);

@@ -23,0 +28,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc