From 580f8ae5c53062d1303307e9d6c4b292cb6c64f3 Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 12:53:36 -0500 Subject: [PATCH 1/7] chore(pkg): Add Prettier to deps --- package.json | 3 ++- yarn.lock | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f3c0935..85bfd2c 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "dependencies": { "coingecko-api": "^1.0.10", "curlrequest": "^1.0.1", - "mathjs": "^8.0.1" + "mathjs": "^8.0.1", + "prettier": "^2.5.1" }, "scripts": { "start": "node src/index.js" diff --git a/yarn.lock b/yarn.lock index e43a28e..cc14209 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,6 +51,11 @@ mathjs@^8.0.1: tiny-emitter "^2.1.0" typed-function "^2.0.0" +prettier@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== + seedrandom@^3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" From f181e7a582ecb595c2652670c06721c85bbd305a Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 12:55:25 -0500 Subject: [PATCH 2/7] chore(pkg): Add 'format' script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 85bfd2c..9422ad0 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "prettier": "^2.5.1" }, "scripts": { - "start": "node src/index.js" + "start": "node src/index.js", + "format": "prettier -w ./config ./src" } } From 979680d7d69d4fe56b49e1a8b3e7876f101cf22c Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 12:57:29 -0500 Subject: [PATCH 3/7] chore(pkg): Add Husky to deps --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 9422ad0..4b4546f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "dependencies": { "coingecko-api": "^1.0.10", "curlrequest": "^1.0.1", + "husky": "^7.0.4", "mathjs": "^8.0.1", "prettier": "^2.5.1" }, diff --git a/yarn.lock b/yarn.lock index cc14209..276c991 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,6 +32,11 @@ fraction.js@^4.0.12: resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.12.tgz#0526d47c65a5fb4854df78bc77f7bec708d7b8c3" integrity sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA== +husky@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" + integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== + javascript-natural-sort@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" From 1acf2eeecfc2078152f7eb2c7e5c943b43edbe66 Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 22:26:23 -0500 Subject: [PATCH 4/7] chore: Format --- config/userInput.json | 31 +-- src/api.js | 219 +++++++++-------- src/curl.js | 235 ++++++++++--------- src/fileWorker.js | 148 ++++++------ src/gatherData.js | 39 ++- src/index.js | 213 +++++++++++------ src/utils.js | 534 ++++++++++++++++++++++++------------------ 7 files changed, 803 insertions(+), 616 deletions(-) diff --git a/config/userInput.json b/config/userInput.json index d29c286..3189b9e 100644 --- a/config/userInput.json +++ b/config/userInput.json @@ -1,21 +1,22 @@ { -"start": "2021-01-01", -"end": "2021-01-31", -"currency": "CHF", -"priceData": "true", -"exportOutput": "true", -"addresses": [ + "start": "2021-01-01", + "end": "2021-01-31", + "currency": "CHF", + "priceData": "true", + "exportOutput": "true", + "addresses": [ { - "name": "Account 1", - "address":"G1rrUNQSk7CjjEmLSGcpNu72tVtyzbWdUvgmSer9eBitXWf", - "startBalance": 10000, - "network": "Kusama" + "name": "Account 1", + "address": "G1rrUNQSk7CjjEmLSGcpNu72tVtyzbWdUvgmSer9eBitXWf", + "startBalance": 10000, + "network": "Kusama" }, { - "name":"Account 2", - "address": "15fTw39Ju2jJiHeGe1fJ5DtgugUauy9tr2HZuiRNFwqnGQ1Q", - "startBalance": 20000, - "network": "Polkadot" + "name": "Account 2", + "address": "15fTw39Ju2jJiHeGe1fJ5DtgugUauy9tr2HZuiRNFwqnGQ1Q", + "startBalance": 20000, + "network": "Polkadot" } -]} \ No newline at end of file + ] +} diff --git a/src/api.js b/src/api.js index 68d598c..74953bc 100644 --- a/src/api.js +++ b/src/api.js @@ -1,123 +1,138 @@ -import CoinGecko from 'coingecko-api'; -import { ceil, round } from 'mathjs'; -import { transformDDMMYYYtoUnix } from './utils.js'; - - - -export async function addPriceData(obj){ - let priceObject = await _getPriceObject(obj); - var prices; - var total_volume; - - - prices = _arrayToObject(priceObject.data.prices, "price"); - total_volume = _arrayToObject(priceObject.data.total_volumes, "volume"); - - // set index to first day price were available to avoid looking for prices where are none - let i = _setIndex(obj); - - for(i;i x.timestamp == tmp).price,2); - obj.data.list[i].volume = total_volume.find(x => x.timestamp == tmp).volume; - } - return obj; +import CoinGecko from "coingecko-api"; +import { ceil, round } from "mathjs"; +import { transformDDMMYYYtoUnix } from "./utils.js"; + +export async function addPriceData(obj) { + let priceObject = await _getPriceObject(obj); + var prices; + var total_volume; + + prices = _arrayToObject(priceObject.data.prices, "price"); + total_volume = _arrayToObject(priceObject.data.total_volumes, "volume"); + + // set index to first day price were available to avoid looking for prices where are none + let i = _setIndex(obj); + + for (i; i < obj.data.list.length; i++) { + let tmp = transformDDMMYYYtoUnix(obj.data.list[i].day); + obj.data.list[i].price = round( + prices.find((x) => x.timestamp == tmp).price, + 2 + ); + obj.data.list[i].volume = total_volume.find( + (x) => x.timestamp == tmp + ).volume; + } + return obj; } -async function _getPriceObject(obj){ - const CoinGeckoClient = new CoinGecko(); - var priceObject; - - let start = transformDDMMYYYtoUnix(obj.data.list[0].day); - let end = transformDDMMYYYtoUnix(obj.data.list.slice(-1)[0].day); - - // Avoid getting hourly or minute price data. - end = _checkDuration(start, end); - - try{ - priceObject = await CoinGeckoClient.coins.fetchMarketChartRange(obj.network, { - from: start, - to: end, - vs_currency: obj.currency, - }); - } catch (e){ - console.log('Error in parsing CoinGecko Data' + e); - } - return priceObject; +async function _getPriceObject(obj) { + const CoinGeckoClient = new CoinGecko(); + var priceObject; + + let start = transformDDMMYYYtoUnix(obj.data.list[0].day); + let end = transformDDMMYYYtoUnix(obj.data.list.slice(-1)[0].day); + + // Avoid getting hourly or minute price data. + end = _checkDuration(start, end); + + try { + priceObject = await CoinGeckoClient.coins.fetchMarketChartRange( + obj.network, + { + from: start, + to: end, + vs_currency: obj.currency, + } + ); + } catch (e) { + console.log("Error in parsing CoinGecko Data" + e); + } + return priceObject; } /* CoinGecko API returns a list of arrays without a key, value pair. This function creates an object from that list. */ -function _arrayToObject(array, key){ - let name = key; - let obj = []; - // populate the key - for(let i=0; i transformDDMMYYYtoUnix(x.day) > 1597708800); - } - - if(network == 'kusama'){ - index = obj.data.list.findIndex(x => transformDDMMYYYtoUnix(x.day) > 1568851200); - } - - if(network == 'moonriver' ){ - index = obj.data.list.findIndex(x => transformDDMMYYYtoUnix(x.day) > 1630022400); - } - - if(network == 'moonbeam'){ - index = obj.data.list.findIndex(x => transformDDMMYYYtoUnix(x.day) > 1641884400); - } - - if(network == 'shiden'){ - index = obj.data.list.findIndex(x => transformDDMMYYYtoUnix(x.day) > 1630303200); - } - - if(network == 'astar'){ - index = obj.data.list.findIndex(x => transformDDMMYYYtoUnix(x.day) > 1642402800); - } - - - if(index < 0){ - index = 0; - } - - return index; -} \ No newline at end of file +function _setIndex(obj) { + var index; + + let network = obj.network; + + if (network == "polkadot") { + index = obj.data.list.findIndex( + (x) => transformDDMMYYYtoUnix(x.day) > 1597708800 + ); + } + + if (network == "kusama") { + index = obj.data.list.findIndex( + (x) => transformDDMMYYYtoUnix(x.day) > 1568851200 + ); + } + + if (network == "moonriver") { + index = obj.data.list.findIndex( + (x) => transformDDMMYYYtoUnix(x.day) > 1630022400 + ); + } + + if (network == "moonbeam") { + index = obj.data.list.findIndex( + (x) => transformDDMMYYYtoUnix(x.day) > 1641884400 + ); + } + + if (network == "shiden") { + index = obj.data.list.findIndex( + (x) => transformDDMMYYYtoUnix(x.day) > 1630303200 + ); + } + + if (network == "astar") { + index = obj.data.list.findIndex( + (x) => transformDDMMYYYtoUnix(x.day) > 1642402800 + ); + } + + if (index < 0) { + index = 0; + } + + return index; +} diff --git a/src/curl.js b/src/curl.js index 29acf05..2cf1b2b 100644 --- a/src/curl.js +++ b/src/curl.js @@ -1,20 +1,19 @@ -import curl from 'curlrequest'; -import { exportVariable } from './fileWorker.js'; -import { dateToString, transformDDMMYYYtoUnix, min, sleep } from './utils.js'; - - -export async function addStakingData(obj){ - const SLEEP_DELAY=100; - let found = 0; - let stakingObject = {}; - var finished; - let page = -1; - let address = obj.address; - let network = obj.network; - var loopIndex; - let round = 0; - - /* +import curl from "curlrequest"; +import { exportVariable } from "./fileWorker.js"; +import { dateToString, transformDDMMYYYtoUnix, min, sleep } from "./utils.js"; + +export async function addStakingData(obj) { + const SLEEP_DELAY = 100; + let found = 0; + let stakingObject = {}; + var finished; + let page = -1; + let address = obj.address; + let network = obj.network; + var loopIndex; + let round = 0; + + /* This function runs at least once and parses the staking info for the given address. The API is structured in a way that you specify which page is shown (probably like in the webpage). There is a maximum of 100 entries per page and the first page is 0. The following loop has two for loops. The two loops compare every day of the object (by the user) with all entries of the staking object. This is necessary since you can @@ -23,58 +22,73 @@ export async function addStakingData(obj){ specified range of the user. Only then can we be sure that we have all the data. If this is not the case, we parse the next 100 entries of the next page. */ - do { - page += 1; - round += 1; - stakingObject = await getStakingObject(address, page, network); - // Delay to avoid hitting API rate limit - await sleep(SLEEP_DELAY); + do { + page += 1; + round += 1; + stakingObject = await getStakingObject(address, page, network); + // Delay to avoid hitting API rate limit + await sleep(SLEEP_DELAY); - // Break loop if none rewards have been found for the address. - if(stakingObject.data.count == 0 || stakingObject.data.list === null){ - break; - } + // Break loop if none rewards have been found for the address. + if (stakingObject.data.count == 0 || stakingObject.data.list === null) { + break; + } - if(page==0){ - loopIndex = min(stakingObject.data.count, 100); - } else { - loopIndex = min(stakingObject.data.count - page*100,100); + if (page == 0) { + loopIndex = min(stakingObject.data.count, 100); + } else { + loopIndex = min(stakingObject.data.count - page * 100, 100); + } + for (let i = 0; i < obj.data.numberOfDays; i++) { + for (let x = 0; x < loopIndex; x++) { + let tmp = dateToString( + new Date(stakingObject.data.list[x].block_timestamp * 1000) + ); + if ( + (tmp == obj.data.list[i].day) & + (stakingObject.data.list[x].event_id == "Reward") + ) { + found += 1; + // if we already filled out the entries of a specific day. We then just concanate strings or add values. + if (obj.data.list[i].numberPayouts >= 1) { + obj.data.list[i].amountPlanks = + obj.data.list[i].amountPlanks + + parseInt(stakingObject.data.list[x].amount); + obj.data.list[i].numberPayouts = obj.data.list[i].numberPayouts + 1; + obj.data.list[i].blockNumber = + obj.data.list[i].blockNumber + + " and " + + stakingObject.data.list[x].block_num; + obj.data.list[i].extrinsicHash = + obj.data.list[i].extrinsicHash + + " and " + + stakingObject.data.list[x].extrinsic_hash; + // if an entry has only the default values we add the ones from the staking object. + } else { + obj.data.list[i].amountPlanks = parseInt( + stakingObject.data.list[x].amount + ); + obj.data.list[i].numberPayouts = obj.data.list[i].numberPayouts + 1; + obj.data.list[i].blockNumber = stakingObject.data.list[x].block_num; + obj.data.list[i].extrinsicHash = + stakingObject.data.list[x].extrinsic_hash; + } } - for(let i=0; i < obj.data.numberOfDays; i++){ - for(let x = 0; x < loopIndex; x++){ - let tmp = dateToString(new Date(stakingObject.data.list[x].block_timestamp * 1000)); - if(tmp == obj.data.list[i].day & stakingObject.data.list[x].event_id == "Reward"){ - found += 1; - // if we already filled out the entries of a specific day. We then just concanate strings or add values. - if(obj.data.list[i].numberPayouts >= 1){ - obj.data.list[i].amountPlanks = obj.data.list[i].amountPlanks + parseInt(stakingObject.data.list[x].amount); - obj.data.list[i].numberPayouts = obj.data.list[i].numberPayouts + 1; - obj.data.list[i].blockNumber = obj.data.list[i].blockNumber + ' and ' + stakingObject.data.list[x].block_num; - obj.data.list[i].extrinsicHash = obj.data.list[i].extrinsicHash + ' and ' + stakingObject.data.list[x].extrinsic_hash; - // if an entry has only the default values we add the ones from the staking object. - } else { - obj.data.list[i].amountPlanks = parseInt(stakingObject.data.list[x].amount); - obj.data.list[i].numberPayouts = obj.data.list[i].numberPayouts + 1; - obj.data.list[i].blockNumber = stakingObject.data.list[x].block_num; - obj.data.list[i].extrinsicHash = stakingObject.data.list[x].extrinsic_hash; - } - } - } - } - finished = checkIfEnd(stakingObject, obj.data.list[0].day, loopIndex); - } while (finished == false); - - - obj.data.numberRewardsParsed = found; - - obj.message = 'data collection complete'; - - if(obj.data.numberRewardsParsed == 0){ - console.log('No rewards found to parse for address ' + obj.address); - obj.message = 'No rewards found for this address'; + } } - - return obj; + finished = checkIfEnd(stakingObject, obj.data.list[0].day, loopIndex); + } while (finished == false); + + obj.data.numberRewardsParsed = found; + + obj.message = "data collection complete"; + + if (obj.data.numberRewardsParsed == 0) { + console.log("No rewards found to parse for address " + obj.address); + obj.message = "No rewards found for this address"; + } + + return obj; } /* This function checks if the loop should continue. It should continue whenever the last day retrieved by the staking object retrieved has a larger @@ -82,56 +96,57 @@ value (i.e. lies more towards the present) than the last day of the desired poin we know that there potentially are more rewards to get. */ -function checkIfEnd(stakingObj, lastDay, loopIndex){ - let finished = true; - let lastDayStakingObj = stakingObj.data.list.slice(-1)[0].block_timestamp; +function checkIfEnd(stakingObj, lastDay, loopIndex) { + let finished = true; + let lastDayStakingObj = stakingObj.data.list.slice(-1)[0].block_timestamp; - if(transformDDMMYYYtoUnix(lastDay) < lastDayStakingObj && loopIndex == 100){ - finished = false; - } - return finished; + if (transformDDMMYYYtoUnix(lastDay) < lastDayStakingObj && loopIndex == 100) { + finished = false; + } + return finished; } -async function getStakingObject(address, page, network){ - let breakPoint = 0; - let continueLoop = true; - - let stakingObject = {}; - - let url = 'https://' + network + '.api.subscan.io/api/scan/account/reward_slash'; - - var options = { - url: url, - method: 'POST', - headers: {'Content-Type': 'application/json'}, - data: JSON.stringify({ - 'row':100, - 'page': page, - 'address': address - }), - }; - - // Sometimes the staking object is not properly transmitted. We try it again 10 times. - while( continueLoop & breakPoint < 10 ) { - stakingObject = await curlRequest(options); - try { - stakingObject = JSON.parse(stakingObject); - continueLoop = false; - } catch(e) { - breakPoint += 1; - } +async function getStakingObject(address, page, network) { + let breakPoint = 0; + let continueLoop = true; + + let stakingObject = {}; + + let url = + "https://" + network + ".api.subscan.io/api/scan/account/reward_slash"; + + var options = { + url: url, + method: "POST", + headers: { "Content-Type": "application/json" }, + data: JSON.stringify({ + row: 100, + page: page, + address: address, + }), + }; + + // Sometimes the staking object is not properly transmitted. We try it again 10 times. + while (continueLoop & (breakPoint < 10)) { + stakingObject = await curlRequest(options); + try { + stakingObject = JSON.parse(stakingObject); + continueLoop = false; + } catch (e) { + breakPoint += 1; } - return stakingObject; + } + return stakingObject; } -async function curlRequest(options){ - return new Promise(function (resolve, reject){ - curl.request(options, (err,data) => { - if (!err){ - resolve(data); - } else { - reject(err); - } - }); +async function curlRequest(options) { + return new Promise(function (resolve, reject) { + curl.request(options, (err, data) => { + if (!err) { + resolve(data); + } else { + reject(err); + } }); + }); } diff --git a/src/fileWorker.js b/src/fileWorker.js index 7aaca38..5f5cf40 100644 --- a/src/fileWorker.js +++ b/src/fileWorker.js @@ -1,91 +1,105 @@ -import fs from 'fs'; +import fs from "fs"; -export function exportVariable(data, name){ - try { - fs.writeFileSync(name, data); - } catch (err) { - console.error(err); - } +export function exportVariable(data, name) { + try { + fs.writeFileSync(name, data); + } catch (err) { + console.error(err); + } } export function readJSON(filePath) { - const rawContent = fs.readFileSync(filePath); + const rawContent = fs.readFileSync(filePath); + + return JSON.parse(rawContent); +} + +export function writeCSV(obj, name) { + const filename = name; - return JSON.parse(rawContent); + try { + fs.writeFileSync(filename, extractAsCSV(obj)); + } catch (err) { + console.error(err); } +} - export function writeCSV(obj, name){ - const filename = name; +function extractAsCSV(obj) { + const header = [ + "Prices from CoinGecko & Staking Rewards from Subscan.io \n" + + "Day, Price in " + + obj.currency + + ", Daily Volume in " + + obj.currency + + ", Staking Rewards in " + + obj.ticker + + ", Number of Payouts" + + ", Value in Fiat", + ]; - try { - fs.writeFileSync(filename, extractAsCSV(obj)); - } catch (err){ - console.error(err); - } - } - - function extractAsCSV(obj){ - const header = [ - "Prices from CoinGecko & Staking Rewards from Subscan.io \n" + - "Day, Price in " + obj.currency + - ", Daily Volume in " + obj.currency + - ", Staking Rewards in " + obj.ticker + - ", Number of Payouts" + - ", Value in Fiat" - ]; - - const rows = obj.data.list - .filter(entry => entry.numberPayouts > 0) - .map(entry => `${entry.day}, ${entry.price}, ${entry.volume}, ${entry.amountHumanReadable}, ${entry.numberPayouts}, ${entry.valueFiat}`); - - return header.concat(rows).join("\n"); - } - - export function writeOverviewCSV(i, i_max, obj, csv){ - /* + const rows = obj.data.list + .filter((entry) => entry.numberPayouts > 0) + .map( + (entry) => + `${entry.day}, ${entry.price}, ${entry.volume}, ${entry.amountHumanReadable}, ${entry.numberPayouts}, ${entry.valueFiat}` + ); + + return header.concat(rows).join("\n"); +} + +export function writeOverviewCSV(i, i_max, obj, csv) { + /* This function creates an overview csv that holds aggregated information about the addresses. I am passing back and forth the csv that gets enriched with every loop in index.js. When the loop ends, i.e., when i == i_max, then the csv is written. */ - const filename = 'Overview.csv'; - var row; - const header = [ - "Prices from CoinGecko & Staking Rewards from Subscan.io \n" + + const filename = "Overview.csv"; + var row; + const header = [ + "Prices from CoinGecko & Staking Rewards from Subscan.io \n" + "Address " + - ", Network " + + ", Network " + ", Ticker" + ", Number of Tokens" + - ", Value in " + obj.currency - ]; + ", Value in " + + obj.currency, + ]; - /* + /* We check here if there were any rewards in the obj. If not, we do not want to write a line into the overview csv. However, we cannot just skip this function, because we an empty address could be the first entry (which then require to have the header written) or the last entry (which would write the file). Therefore, we simply write an empty string. */ - if(obj.message == 'No rewards found for this address'){ - row = ''; - } else { - row = obj.address + ',' + obj.network.toUpperCase() + ',' + obj.ticker + ',' + obj.totalAmountHumanReadable + ',' + obj.totalValueFiat + "\n"; - } + if (obj.message == "No rewards found for this address") { + row = ""; + } else { + row = + obj.address + + "," + + obj.network.toUpperCase() + + "," + + obj.ticker + + "," + + obj.totalAmountHumanReadable + + "," + + obj.totalValueFiat + + "\n"; + } - // If it is the first address that has been parsed, we want to create the overview csv - if(i == 0){ - csv = header.concat(row).join("\n"); - } + // If it is the first address that has been parsed, we want to create the overview csv + if (i == 0) { + csv = header.concat(row).join("\n"); + } - if(i > 0){ - csv += row; - } + if (i > 0) { + csv += row; + } - if(i == (i_max-1)){ - try { - fs.writeFileSync(filename, csv); - } catch (err){ - console.error(err); - } + if (i == i_max - 1) { + try { + fs.writeFileSync(filename, csv); + } catch (err) { + console.error(err); } - return csv; } - - - \ No newline at end of file + return csv; +} diff --git a/src/gatherData.js b/src/gatherData.js index bc6975e..b581b5b 100644 --- a/src/gatherData.js +++ b/src/gatherData.js @@ -1,18 +1,33 @@ import { addPriceData } from "./api.js"; import { makeDaysArray, initializeObject } from "./utils.js"; -import { addStakingData } from './curl.js'; +import { addStakingData } from "./curl.js"; -export async function gatherData(start, end, network, address, currency, priceData, startBalance, ticker){ - - let obj = {}; - let daysArray = []; +export async function gatherData( + start, + end, + network, + address, + currency, + priceData, + startBalance, + ticker +) { + let obj = {}; + let daysArray = []; - daysArray = makeDaysArray(new Date(start), new Date(end)); - obj = initializeObject(daysArray, network, address, currency, startBalance, ticker); - if(priceData == 'true'){ - obj = await addPriceData(obj); - } - obj = await addStakingData(obj); + daysArray = makeDaysArray(new Date(start), new Date(end)); + obj = initializeObject( + daysArray, + network, + address, + currency, + startBalance, + ticker + ); + if (priceData == "true") { + obj = await addPriceData(obj); + } + obj = await addStakingData(obj); - return obj; + return obj; } diff --git a/src/index.js b/src/index.js index 98cf0e1..0f279cb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,118 +1,179 @@ -import { gatherData } from './gatherData.js'; -import { exportVariable, readJSON, writeCSV, writeOverviewCSV } from './fileWorker.js'; -import { calculateMetrics, verifyUserInput, getTicker, checkPriceAvailablilty } from './utils.js'; - - -async function main () { +import { gatherData } from "./gatherData.js"; +import { + exportVariable, + readJSON, + writeCSV, + writeOverviewCSV, +} from "./fileWorker.js"; +import { + calculateMetrics, + verifyUserInput, + getTicker, + checkPriceAvailablilty, +} from "./utils.js"; + +async function main() { let obj = {}; let csv = []; - let userInput = readJSON('config/userInput.json'); + let userInput = readJSON("config/userInput.json"); let numberPayouts = { - "DOT": 0, - "KSM": 0, - "MOVR":0, - "GLMR": 0, - "SDN": 0, - "ASTR": 0, - } + DOT: 0, + KSM: 0, + MOVR: 0, + GLMR: 0, + SDN: 0, + ASTR: 0, + }; let totalStaked = { - "DOT": 0, - "KSM": 0, - "MOVR": 0, - "GLMR": 0, - "SDN": 0, - "ASTR": 0, - } + DOT: 0, + KSM: 0, + MOVR: 0, + GLMR: 0, + SDN: 0, + ASTR: 0, + }; let totalFiatToken = { - "DOT": 0, - "KSM": 0, - "MOVR": 0, - "GLMR": 0, - "SDN": 0, - "ASTR": 0, - } + DOT: 0, + KSM: 0, + MOVR: 0, + GLMR: 0, + SDN: 0, + ASTR: 0, + }; let totalFiat = 0; - - for(let i = 0; i < userInput.addresses.length; i++){ + for (let i = 0; i < userInput.addresses.length; i++) { verifyUserInput(userInput); let network = userInput.addresses[i].network.toLowerCase(); let priceData = checkPriceAvailablilty(userInput, network); let start = userInput.start; let end = userInput.end; - let address = userInput.addresses[i].address; + let address = userInput.addresses[i].address; let currency = userInput.currency; let exportOutput = userInput.exportOutput; let startBalance = userInput.addresses[i].startBalance; let ticker = getTicker(network); - obj = await gatherData(start, end, network, address, currency, priceData, startBalance, ticker); - + obj = await gatherData( + start, + end, + network, + address, + currency, + priceData, + startBalance, + ticker + ); + // otherwise there were no rewards - if(obj.data.numberRewardsParsed > 0){ + if (obj.data.numberRewardsParsed > 0) { obj = calculateMetrics(obj); } - if(exportOutput == "true" & obj.message != 'No rewards found for this address'){ - exportVariable(JSON.stringify(obj), userInput.addresses[i].name + ' ' + obj.address + '.json'); - writeCSV(obj, userInput.addresses[i].name + ' ' + obj.address + '.csv'); + if ( + (exportOutput == "true") & + (obj.message != "No rewards found for this address") + ) { + exportVariable( + JSON.stringify(obj), + userInput.addresses[i].name + " " + obj.address + ".json" + ); + writeCSV(obj, userInput.addresses[i].name + " " + obj.address + ".csv"); } /* Creates an overview csv that holds a summary of all addresses. I need to pass it outside of the previous if-condition because it could be that the last address didn't have any rewards which would lead to the fact that the file would never be written. I included a flag in the writeOverviewCSV function to skip writing a line for addresses that have no rewards. */ - if(exportOutput == "true"){ - csv = writeOverviewCSV(i, userInput.addresses.length, obj, csv); + if (exportOutput == "true") { + csv = writeOverviewCSV(i, userInput.addresses.length, obj, csv); } - totalFiat = totalFiat + obj.totalValueFiat; - if(network == "polkadot"){ - totalStaked.DOT = totalStaked.DOT + obj.totalAmountHumanReadable; - numberPayouts.DOT = numberPayouts.DOT + obj.data.numberRewardsParsed; - totalFiatToken.DOT = totalFiatToken.DOT + obj.totalValueFiat; + if (network == "polkadot") { + totalStaked.DOT = totalStaked.DOT + obj.totalAmountHumanReadable; + numberPayouts.DOT = numberPayouts.DOT + obj.data.numberRewardsParsed; + totalFiatToken.DOT = totalFiatToken.DOT + obj.totalValueFiat; } else if (network == "kusama") { - numberPayouts.KSM = numberPayouts.KSM + obj.data.numberRewardsParsed; - totalStaked.KSM = totalStaked.KSM + obj.totalAmountHumanReadable; - totalFiatToken.KSM = totalFiatToken.KSM + obj.totalValueFiat; - } else if (network == "moonriver"){ - numberPayouts.MOVR = numberPayouts.MOVR + obj.data.numberRewardsParsed; - totalStaked.MOVR = totalStaked.MOVR + obj.totalAmountHumanReadable; - totalFiatToken.MOVR = totalFiatToken.MOVR + obj.totalValueFiat; - } else if (network == "moonbeam"){ - numberPayouts.GLMR = numberPayouts.GLMR + obj.data.numberRewardsParsed - totalStaked.GLMR = totalStaked.GLMR + obj.totalAmountHumanReadable; - totalFiatToken.GLMR = totalFiatToken.GLMR + obj.totalValueFiat; - } else if (network == "shiden"){ - numberPayouts.SDN = numberPayouts.SDN + obj.data.numberRewardsParsed - totalStaked.SDN = totalStaked.SDN + obj.totalAmountHumanReadable; - totalFiatToken.SDN = totalFiatToken.SDN + obj.totalValueFiat; - } else if (network == "astar"){ - numberPayouts.ASTR = numberPayouts.ASTR + obj.data.numberRewardsParsed + numberPayouts.KSM = numberPayouts.KSM + obj.data.numberRewardsParsed; + totalStaked.KSM = totalStaked.KSM + obj.totalAmountHumanReadable; + totalFiatToken.KSM = totalFiatToken.KSM + obj.totalValueFiat; + } else if (network == "moonriver") { + numberPayouts.MOVR = numberPayouts.MOVR + obj.data.numberRewardsParsed; + totalStaked.MOVR = totalStaked.MOVR + obj.totalAmountHumanReadable; + totalFiatToken.MOVR = totalFiatToken.MOVR + obj.totalValueFiat; + } else if (network == "moonbeam") { + numberPayouts.GLMR = numberPayouts.GLMR + obj.data.numberRewardsParsed; + totalStaked.GLMR = totalStaked.GLMR + obj.totalAmountHumanReadable; + totalFiatToken.GLMR = totalFiatToken.GLMR + obj.totalValueFiat; + } else if (network == "shiden") { + numberPayouts.SDN = numberPayouts.SDN + obj.data.numberRewardsParsed; + totalStaked.SDN = totalStaked.SDN + obj.totalAmountHumanReadable; + totalFiatToken.SDN = totalFiatToken.SDN + obj.totalValueFiat; + } else if (network == "astar") { + numberPayouts.ASTR = numberPayouts.ASTR + obj.data.numberRewardsParsed; totalStaked.ASTR = totalStaked.ASTR + obj.totalAmountHumanReadable; totalFiatToken.ASTR = totalFiatToken.ASTR + obj.totalValueFiat; } } - - console.log('The following table lists all found rewards and values are expressed in ' + obj.currency); - - - const DOT = {"Name": "DOT", "Nr. Payouts": numberPayouts.DOT, "Number of Tokens": totalStaked.DOT, "Value": totalFiatToken.DOT}; - const KSM = {"Name": "KSM", "Nr. Payouts": numberPayouts.KSM, "Number of Tokens": totalStaked.KSM, "Value": totalFiatToken.KSM}; - const GLMR = {"Name": "GLMR", "Nr. Payouts": numberPayouts.GLMR, "Number of Tokens": totalStaked.GLMR, "Value": totalFiatToken.GLMR} - const MOVR = {"Name": "MOVR", "Nr. Payouts": numberPayouts.MOVR, "Number of Tokens": totalStaked.MOVR, "Value": totalFiatToken.MOVR}; - const SDN = {"Name": "SDN", "Nr. Payouts": numberPayouts.SDN, "Number of Tokens": totalStaked.SDN, "Value": totalFiatToken.SDN}; - const ASTR = {"Name": "ASTR", "Nr. Payouts": numberPayouts.ASTR, "Number of Tokens": totalStaked.ASTR, "Value": totalFiatToken.ASTR}; - + console.log( + "The following table lists all found rewards and values are expressed in " + + obj.currency + ); + + const DOT = { + Name: "DOT", + "Nr. Payouts": numberPayouts.DOT, + "Number of Tokens": totalStaked.DOT, + Value: totalFiatToken.DOT, + }; + const KSM = { + Name: "KSM", + "Nr. Payouts": numberPayouts.KSM, + "Number of Tokens": totalStaked.KSM, + Value: totalFiatToken.KSM, + }; + const GLMR = { + Name: "GLMR", + "Nr. Payouts": numberPayouts.GLMR, + "Number of Tokens": totalStaked.GLMR, + Value: totalFiatToken.GLMR, + }; + const MOVR = { + Name: "MOVR", + "Nr. Payouts": numberPayouts.MOVR, + "Number of Tokens": totalStaked.MOVR, + Value: totalFiatToken.MOVR, + }; + const SDN = { + Name: "SDN", + "Nr. Payouts": numberPayouts.SDN, + "Number of Tokens": totalStaked.SDN, + Value: totalFiatToken.SDN, + }; + const ASTR = { + Name: "ASTR", + "Nr. Payouts": numberPayouts.ASTR, + "Number of Tokens": totalStaked.ASTR, + Value: totalFiatToken.ASTR, + }; - console.table([DOT, KSM, GLMR, MOVR, ASTR, SDN]); - console.log('The total value of all payouts is ' + totalFiat + ' ' + obj.currency + ' (based on daily prices).'); - console.log('For more information, open the CSV file(s) or copy the content of the JSON file(s) into http://jsonviewer.stack.hu/ (click format).'); + console.log( + "The total value of all payouts is " + + totalFiat + + " " + + obj.currency + + " (based on daily prices)." + ); + console.log( + "For more information, open the CSV file(s) or copy the content of the JSON file(s) into http://jsonviewer.stack.hu/ (click format)." + ); } -main().catch(console.error).finally(() => process.exit()); \ No newline at end of file +main() + .catch(console.error) + .finally(() => process.exit()); diff --git a/src/utils.js b/src/utils.js index 4338cf9..28bdeb1 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,278 +1,344 @@ -import { round, pow } from 'mathjs'; +import { round, pow } from "mathjs"; export function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +export function dateToString(date) { + let day = date.getDate().toString(); + let month = (date.getMonth() + 1).toString(); + let year = date.getFullYear().toString(); + + if (day.length == 1) { + day = day.concat("0"); + day = _reverseString(day); } -export function dateToString(date){ - let day = date.getDate().toString(); - let month = (date.getMonth() + 1).toString(); - let year = date.getFullYear().toString(); - - if(day.length == 1){ - day = day.concat('0'); - day = _reverseString(day); - } - - if(month.length == 1){ - month = month.concat('0'); - month = _reverseString(month); - } - return day.concat('-', month, '-', year); + if (month.length == 1) { + month = month.concat("0"); + month = _reverseString(month); } + return day.concat("-", month, "-", year); +} export function makeDaysArray(startDate, endDate) { - let dates = []; - const theDate = new Date(startDate); - while (theDate < endDate) { - dates = [...dates, new Date(theDate)]; - theDate.setDate(theDate.getDate() + 1); - } - dates = [...dates, endDate]; - dates = _transformArrayToString(dates); - return dates; - }; - -export function initializeObject(daysArray, network, address, currency, startBalance, ticker){ - let obj = { - 'message': 'empty', - 'address': address, - 'network': network, - 'ticker' : ticker, - 'currency': currency, - 'startBalance': startBalance, - 'firstReward': '', - 'lastReward': '', - 'annualizedReturn':0, - 'currentValueRewardsFiat':0, - 'totalAmountHumanReadable':0, - 'totalValueFiat': 0, - 'data':{ - 'numberRewardsParsed': 0, - 'numberOfDays': daysArray.length, - 'list':[] - } - } - for(let i = 0; i < daysArray.length; i++){ - obj.data.list[i] = { - 'day' : daysArray[i], - 'blockNumber': '', - 'extrinsicHash': '', - 'price': 0, - 'volume': 0, - 'amountPlanks': 0, - 'numberPayouts':0, - 'amountHumanReadable': 0, - 'valueFiat':0 - } - } - return obj; + let dates = []; + const theDate = new Date(startDate); + while (theDate < endDate) { + dates = [...dates, new Date(theDate)]; + theDate.setDate(theDate.getDate() + 1); + } + dates = [...dates, endDate]; + dates = _transformArrayToString(dates); + return dates; } -function _reverseString(string){ - var i; - let length = string.length; - var tmp_string = ''; - - for(i = 0; i < string.length; i++){ - tmp_string = tmp_string.concat(string[length-1]); - length -= 1; - } - return tmp_string; +export function initializeObject( + daysArray, + network, + address, + currency, + startBalance, + ticker +) { + let obj = { + message: "empty", + address: address, + network: network, + ticker: ticker, + currency: currency, + startBalance: startBalance, + firstReward: "", + lastReward: "", + annualizedReturn: 0, + currentValueRewardsFiat: 0, + totalAmountHumanReadable: 0, + totalValueFiat: 0, + data: { + numberRewardsParsed: 0, + numberOfDays: daysArray.length, + list: [], + }, + }; + for (let i = 0; i < daysArray.length; i++) { + obj.data.list[i] = { + day: daysArray[i], + blockNumber: "", + extrinsicHash: "", + price: 0, + volume: 0, + amountPlanks: 0, + numberPayouts: 0, + amountHumanReadable: 0, + valueFiat: 0, + }; + } + return obj; } -function _transformArrayToString(array){ - let newArray = []; - - for(let i = 0; i < array.length; i++){ - newArray[i] = dateToString(array[i]); - } - return newArray; +function _reverseString(string) { + var i; + let length = string.length; + var tmp_string = ""; + + for (i = 0; i < string.length; i++) { + tmp_string = tmp_string.concat(string[length - 1]); + length -= 1; + } + return tmp_string; } -export function transformDDMMYYYtoUnix(dateString){ +function _transformArrayToString(array) { + let newArray = []; - var dateParts = dateString.split('-'); - let date = new Date(Date.UTC(+dateParts[2], dateParts[1] - 1, +dateParts[0])); - // CoinGecko defines a day at 12:00am (UTC) which is 7200 after the value given by the date.valueOf() - let unix = date.valueOf() / 1000; - return unix; + for (let i = 0; i < array.length; i++) { + newArray[i] = dateToString(array[i]); + } + return newArray; } -export function min(a,b){ - var min; - if(a>b){ - min = b; - }else { - min = a; - } - return min; +export function transformDDMMYYYtoUnix(dateString) { + var dateParts = dateString.split("-"); + let date = new Date(Date.UTC(+dateParts[2], dateParts[1] - 1, +dateParts[0])); + // CoinGecko defines a day at 12:00am (UTC) which is 7200 after the value given by the date.valueOf() + let unix = date.valueOf() / 1000; + return unix; } -export function calculateMetrics(obj){ - var normalization; +export function min(a, b) { + var min; + if (a > b) { + min = b; + } else { + min = a; + } + return min; +} - normalization = _getDenomination(obj.network); +export function calculateMetrics(obj) { + var normalization; - for(let i = 0; i < obj.data.numberOfDays; i++){ - // generate new metrics - obj.data.list[i].amountHumanReadable = obj.data.list[i].amountPlanks * normalization; - obj.data.list[i].valueFiat = obj.data.list[i].amountHumanReadable * obj.data.list[i].price; - obj.data.list[i].price = obj.data.list[i].price; + normalization = _getDenomination(obj.network); - // add values of each day to general metrics. - obj.totalValueFiat = obj.totalValueFiat + obj.data.list[i].valueFiat; - obj.totalAmountHumanReadable = obj.totalAmountHumanReadable + obj.data.list[i].amountHumanReadable; - } + for (let i = 0; i < obj.data.numberOfDays; i++) { + // generate new metrics + obj.data.list[i].amountHumanReadable = + obj.data.list[i].amountPlanks * normalization; + obj.data.list[i].valueFiat = + obj.data.list[i].amountHumanReadable * obj.data.list[i].price; + obj.data.list[i].price = obj.data.list[i].price; + + // add values of each day to general metrics. + obj.totalValueFiat = obj.totalValueFiat + obj.data.list[i].valueFiat; + obj.totalAmountHumanReadable = + obj.totalAmountHumanReadable + obj.data.list[i].amountHumanReadable; + } + + obj.totalValueFiat = round(obj.totalValueFiat, 2); + obj.currentValueRewardsFiat = round( + obj.totalAmountHumanReadable * obj.data.list[0].price, + 2 + ); + obj.annualizedReturn = _calculateAnnualizedReturn(obj); - obj.totalValueFiat = round(obj.totalValueFiat,2); - obj.currentValueRewardsFiat = round(obj.totalAmountHumanReadable * obj.data.list[0].price,2); - obj.annualizedReturn = _calculateAnnualizedReturn(obj); - - return obj; + return obj; } -function _calculateAnnualizedReturn(obj){ - var annualized; - var firstAndLastReward; - var daysBetweenRewards; - - firstAndLastReward = _getFirstandLastReward(obj); - obj.firstReward = firstAndLastReward.firstReward; - obj.lastReward = firstAndLastReward.lastReward; - //added one day because users must lock for one day and wait. - daysBetweenRewards = ((transformDDMMYYYtoUnix(obj.lastReward) - transformDDMMYYYtoUnix(obj.firstReward)) / 60 / 60 / 24) + 1; - let rateOfReturn = 1 + obj.totalAmountHumanReadable /obj.startBalance; - let daysFraction = 365 / daysBetweenRewards; - annualized = pow(rateOfReturn,daysFraction) - 1; - - return annualized; +function _calculateAnnualizedReturn(obj) { + var annualized; + var firstAndLastReward; + var daysBetweenRewards; + + firstAndLastReward = _getFirstandLastReward(obj); + obj.firstReward = firstAndLastReward.firstReward; + obj.lastReward = firstAndLastReward.lastReward; + //added one day because users must lock for one day and wait. + daysBetweenRewards = + (transformDDMMYYYtoUnix(obj.lastReward) - + transformDDMMYYYtoUnix(obj.firstReward)) / + 60 / + 60 / + 24 + + 1; + let rateOfReturn = 1 + obj.totalAmountHumanReadable / obj.startBalance; + let daysFraction = 365 / daysBetweenRewards; + annualized = pow(rateOfReturn, daysFraction) - 1; + + return annualized; } -function _getFirstandLastReward(obj){ - let i = 0; - let max = obj.data.numberOfDays; - let x = max - 1; - var firstReward; - var lastReward; - - while (i < max) { - if (obj.data.list[i].numberPayouts != 0) { - firstReward = obj.data.list[i].day; - break; - } - i++; - } +function _getFirstandLastReward(obj) { + let i = 0; + let max = obj.data.numberOfDays; + let x = max - 1; + var firstReward; + var lastReward; - while (x >= 0) { - if (obj.data.list[x].numberPayouts != 0) { - lastReward = obj.data.list[x].day; - break; - } - x--; + while (i < max) { + if (obj.data.list[i].numberPayouts != 0) { + firstReward = obj.data.list[i].day; + break; } - return { - 'firstReward': firstReward, - 'lastReward': lastReward + i++; + } + + while (x >= 0) { + if (obj.data.list[x].numberPayouts != 0) { + lastReward = obj.data.list[x].day; + break; } + x--; + } + return { + firstReward: firstReward, + lastReward: lastReward, + }; } -export function verifyUserInput(userInput){ - let start = new Date(userInput.start); - let end = new Date(userInput.end); +export function verifyUserInput(userInput) { + let start = new Date(userInput.start); + let end = new Date(userInput.end); - if(start > end){ - throw new Error('Start date must be before end date') - } + if (start > end) { + throw new Error("Start date must be before end date"); + } - if(end > new Date()){ - throw new Error('End date is in the future.'); - } + if (end > new Date()) { + throw new Error("End date is in the future."); + } } -export function getTicker(network){ - var ticker; - // Convert to upper case to avoid issue with different user input. - switch(network){ - case 'kusama': - ticker = 'KSM'; - break; - case 'polkadot': - ticker = 'DOT'; - break; - case 'moonriver': - ticker = 'MOVR'; - break; - case 'moonbeam': - ticker = 'GLMR'; - break; - case 'shiden': - ticker = 'SDN'; - break; - case 'astar': - ticker = 'ASTR'; - break; - } - return ticker; +export function getTicker(network) { + var ticker; + // Convert to upper case to avoid issue with different user input. + switch (network) { + case "kusama": + ticker = "KSM"; + break; + case "polkadot": + ticker = "DOT"; + break; + case "moonriver": + ticker = "MOVR"; + break; + case "moonbeam": + ticker = "GLMR"; + break; + case "shiden": + ticker = "SDN"; + break; + case "astar": + ticker = "ASTR"; + break; + } + return ticker; } -export function _getDenomination(network){ - var normalization; - switch(network){ - case 'polkadot': - normalization = 1/10000000000; - break; - case 'kusama': - normalization = 1/1000000000000; - break; - case 'moonriver': - normalization = 1/1000000000000000000; - break; - case 'moonbeam': - normalization = 1/1000000000000000000; - break; - case 'shiden': - normalization = 1/1000000000000000000; - break; - case 'astar': - normalization = 1/1000000000000000000; - break; - } - return normalization; +export function _getDenomination(network) { + var normalization; + switch (network) { + case "polkadot": + normalization = 1 / 10000000000; + break; + case "kusama": + normalization = 1 / 1000000000000; + break; + case "moonriver": + normalization = 1 / 1000000000000000000; + break; + case "moonbeam": + normalization = 1 / 1000000000000000000; + break; + case "shiden": + normalization = 1 / 1000000000000000000; + break; + case "astar": + normalization = 1 / 1000000000000000000; + break; + } + return normalization; } -export function checkPriceAvailablilty(userInput, network){ - let priceData = userInput.priceData; - let end = new Date(userInput.end); +export function checkPriceAvailablilty(userInput, network) { + let priceData = userInput.priceData; + let end = new Date(userInput.end); - if(end.valueOf() < 1597708800000 & network == 'polkadot' & priceData == 'true'){ - console.log('Your requested time window lies before prices are available for ' + network.toUpperCase() + '. Switching off price data.'); - priceData = 'false'; - } - - if(end.valueOf() < 1568851200000 & network == 'kusama' & priceData == 'true'){ - console.log('Your requested time window lies before prices are available for ' + network.toUpperCase() + '. Switching off price data.'); - priceData = 'false'; - } + if ( + (end.valueOf() < 1597708800000) & + (network == "polkadot") & + (priceData == "true") + ) { + console.log( + "Your requested time window lies before prices are available for " + + network.toUpperCase() + + ". Switching off price data." + ); + priceData = "false"; + } - if(end.valueOf() < 1630022400000 & network == 'moonriver' & priceData == 'true'){ - console.log('Your requested time window lies before prices are available for ' + network.toUpperCase() + '. Switching off price data.'); - priceData = 'false'; - } + if ( + (end.valueOf() < 1568851200000) & + (network == "kusama") & + (priceData == "true") + ) { + console.log( + "Your requested time window lies before prices are available for " + + network.toUpperCase() + + ". Switching off price data." + ); + priceData = "false"; + } - if(end.valueOf() < 1641884400000 & network == 'moonbeam' & priceData == 'true'){ - console.log('Your requested time window lies before prices are available for ' + network.toUpperCase() + '. Switching off price data.'); - priceData = 'false'; - } + if ( + (end.valueOf() < 1630022400000) & + (network == "moonriver") & + (priceData == "true") + ) { + console.log( + "Your requested time window lies before prices are available for " + + network.toUpperCase() + + ". Switching off price data." + ); + priceData = "false"; + } - if(end.valueOf() < 1630303200000 & network == 'shiden' & priceData == 'true'){ - console.log('Your requested time window lies before prices are available for ' + network.toUpperCase() + '. Switching off price data.'); - priceData = 'false'; - } + if ( + (end.valueOf() < 1641884400000) & + (network == "moonbeam") & + (priceData == "true") + ) { + console.log( + "Your requested time window lies before prices are available for " + + network.toUpperCase() + + ". Switching off price data." + ); + priceData = "false"; + } + + if ( + (end.valueOf() < 1630303200000) & + (network == "shiden") & + (priceData == "true") + ) { + console.log( + "Your requested time window lies before prices are available for " + + network.toUpperCase() + + ". Switching off price data." + ); + priceData = "false"; + } - if(end.valueOf() < 1642402800000 & network == 'astar' & priceData == 'true'){ - console.log('Your requested time window lies before prices are available for ' + network.toUpperCase() + '. Switching off price data.'); - priceData = 'false'; - } - return priceData; -} \ No newline at end of file + if ( + (end.valueOf() < 1642402800000) & + (network == "astar") & + (priceData == "true") + ) { + console.log( + "Your requested time window lies before prices are available for " + + network.toUpperCase() + + ". Switching off price data." + ); + priceData = "false"; + } + return priceData; +} From b2cb04f36a38e5956bf8bbe644d4c9824900af55 Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 22:26:48 -0500 Subject: [PATCH 5/7] chore(husky): Format on commit --- .husky/pre-commit | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..8ab6149 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run format From 3843a377565c27a27bd4698efce413856b0b3458 Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 22:32:10 -0500 Subject: [PATCH 6/7] chore(pkg): Alphabetize scripts --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4b4546f..676c820 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "prettier": "^2.5.1" }, "scripts": { - "start": "node src/index.js", - "format": "prettier -w ./config ./src" + "format": "prettier -w ./config ./src", + "start": "node src/index.js" } } From 15e6831bc567aba8e0b0e66869f27181481db2f1 Mon Sep 17 00:00:00 2001 From: Jesse Mykolyn Date: Fri, 4 Mar 2022 22:32:39 -0500 Subject: [PATCH 7/7] chore(husky): Add hooks in install --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 676c820..143708f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "scripts": { "format": "prettier -w ./config ./src", + "prepare": "husky install", "start": "node src/index.js" } }