From d9aeb93743272dcf71b682a9daccaaab3c4dffb5 Mon Sep 17 00:00:00 2001 From: McCall Alexander Date: Mon, 5 Jul 2021 20:05:26 -0600 Subject: [PATCH 1/5] increased max-old-space-size --- js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/package.json b/js/package.json index e6dc333..eecfa83 100644 --- a/js/package.json +++ b/js/package.json @@ -29,7 +29,7 @@ }, "scripts": { "client": "PORT=3001 FAST_REFRESH=false react-scripts start", - "server": "node -r dotenv/config --trace-warnings --max-old-space-size=13958 server/main.js 2>&1 | tee /tmp/cryptoecon.log", + "server": "node -r dotenv/config --trace-warnings --max-old-space-size=32768 server/main.js 2>&1 | tee /tmp/cryptoecon.log", "dev": "node -r dotenv/config --max-old-space-size=16384 server/main.js", "test-process": "node -r dotenv/config --trace-warnings --max-old-space-size=16384 ./server/worker/process.childprocess.test.js", "refresh-lm-snapshot": "source .env && curl -H 'Content-Type: application/json' -H \"$HEADER_SECRET\" -X POST -d '{\"query\": \"query GetSnapshot { snapshots_new(limit: 1 order_by: {id: desc}) { snapshot_data } }\"}' $SNAPSHOT_URL -o ./snapshots/snapshot_lm_latest.trash.json", From 9dcf4939809b4cc3ff648c046b0e602d0c58cfe9 Mon Sep 17 00:00:00 2001 From: McCall Alexander Date: Tue, 6 Jul 2021 11:05:15 -0600 Subject: [PATCH 2/5] added dynamic network url for snapshots v2 beta --- js/src/api.js | 43 ++++++++++++++++++++++++++----------------- js/src/config.js | 3 ++- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/js/src/api.js b/js/src/api.js index 16d9492..23bdea1 100644 --- a/js/src/api.js +++ b/js/src/api.js @@ -1,7 +1,6 @@ import { networks } from './config'; const serverURL = (() => { let environment = process.env.REACT_APP_DEPLOYMENT_TAG; - // environment = 'devnet'; switch (environment) { case 'production': return 'https://api-cryptoeconomics.sifchain.finance/api'; @@ -14,52 +13,62 @@ const serverURL = (() => { } })(); -const getSnapshotNetworkHeaders = network => ({ - 'snapshot-source': network || networks.MAINNET +const getSnapshotNetworkHeaders = (network) => ({ + 'snapshot-source': network || networks.MAINNET, }); -function handleFailedRequest () { +function handleFailedRequest() { setTimeout(() => { window.location.reload(); }, 3000); } +const getUrl = (network) => { + let url = serverURL; + if (networks.MAINNET_SNAPSHOTS_V2_BETA === network) { + url = 'http://ec2-3-138-153-106.us-east-2.compute.amazonaws.com:3000/api'; + } + return url; +}; export const fetchUsers = (type, network) => { return window - .fetch(`${serverURL}/${type}?key=users`, { - headers: getSnapshotNetworkHeaders(network) + .fetch(`${getUrl(network)}/${type}?key=users`, { + headers: getSnapshotNetworkHeaders(network), }) - .then(response => response.json()) + .then((response) => response.json()) .catch(handleFailedRequest); }; export const fetchUserData = (address, type, timestamp, network) => { return window .fetch( - `${serverURL}/${type}?key=userData&address=${address}${ + `${getUrl(network)}/${type}?key=userData&address=${address}${ timestamp ? `×tamp=${new Date(timestamp).toISOString()}` : `` }`, { - headers: getSnapshotNetworkHeaders(network) + headers: getSnapshotNetworkHeaders(network), } ) - .then(response => response.json()) + .then((response) => response.json()) .catch(handleFailedRequest); }; export const fetchUserTimeSeriesData = (address, type, network) => { return window - .fetch(`${serverURL}/${type}?key=userTimeSeriesData&address=${address}`, { - headers: getSnapshotNetworkHeaders(network) - }) - .then(response => response.json()) + .fetch( + `${getUrl(network)}/${type}?key=userTimeSeriesData&address=${address}`, + { + headers: getSnapshotNetworkHeaders(network), + } + ) + .then((response) => response.json()) .catch(handleFailedRequest); }; export const fetchStack = (type, network) => { return window - .fetch(`${serverURL}/${type}?key=stack`, { - headers: getSnapshotNetworkHeaders(network) + .fetch(`${getUrl(network)}/${type}?key=stack`, { + headers: getSnapshotNetworkHeaders(network), }) - .then(response => response.json()) + .then((response) => response.json()) .catch(handleFailedRequest); }; diff --git a/js/src/config.js b/js/src/config.js index 9483b87..5db66eb 100644 --- a/js/src/config.js +++ b/js/src/config.js @@ -3,7 +3,8 @@ const config = { networks: { MAINNET: 'mainnet', DEVNET: 'devnet', - TESTNET: 'testnet' + TESTNET: 'testnet', + MAINNET_SNAPSHOTS_V2_BETA: 'mainnet_snapshots_v2_beta' }, RECENT_ADDRESS_LIST_STORAGE_KEY: '__recent-address-list' }; From f135217f78cfd6d2c37e05ba7af6b6219abafc40 Mon Sep 17 00:00:00 2001 From: McCall Alexander Date: Tue, 6 Jul 2021 11:17:28 -0600 Subject: [PATCH 3/5] added v2 beta option to network select --- js/src/App.js | 283 +++++++++++++++++++++++------------------------ js/src/config.js | 2 +- 2 files changed, 139 insertions(+), 146 deletions(-) diff --git a/js/src/App.js b/js/src/App.js index 615e3e2..2a1a167 100644 --- a/js/src/App.js +++ b/js/src/App.js @@ -1,7 +1,7 @@ import { START_DATETIME, networks, - RECENT_ADDRESS_LIST_STORAGE_KEY + RECENT_ADDRESS_LIST_STORAGE_KEY, } from './config'; import './App.css'; import React, { useEffect, useMemo, useState } from 'react'; @@ -15,8 +15,8 @@ import { StatBlocks } from './StatBlocks'; import { UserDataSummary } from './UserDataSummary'; // show all fields locally -const SHOULD_HIDE_NON_USER_FRIENDLY_FIELDS = !!process.env - .REACT_APP_DEPLOYMENT_TAG; +const SHOULD_HIDE_NON_USER_FRIENDLY_FIELDS = + !!process.env.REACT_APP_DEPLOYMENT_TAG; const userFieldsToHide = [ 'reservedReward', @@ -26,7 +26,7 @@ const userFieldsToHide = [ 'nextReward', 'nextRewardProjectedFutureReward', 'yearsToMaturity', - 'currentAPYOnTickets' + 'currentAPYOnTickets', ]; const debounce = (fn, ms) => { @@ -40,7 +40,7 @@ const debounce = (fn, ms) => { }; class Router { - constructor (onChange = router => {}) { + constructor(onChange = (router) => {}) { this.query = {}; this.hashData = undefined; this.evaluateHashQueryAndData(); @@ -48,12 +48,12 @@ class Router { this.onChange = onChange; } - evaluateHashQueryAndData () { + evaluateHashQueryAndData() { this.query = this.queryStringToObject(window.location.hash); this.hashData = this.extractHashData(); } - push (hash, queryObject) { + push(hash, queryObject) { const queryStr = this.objectToQueryString(queryObject); console.log(queryStr, queryObject); window.history.pushState(undefined, '', `#${hash || ''}&${queryStr}`); @@ -61,28 +61,25 @@ class Router { // this.onChange(this); } - extractHashData () { + extractHashData() { return ( - (window.location.hash || '') - .substr(1) - .split('&') - .shift() || undefined + (window.location.hash || '').substr(1).split('&').shift() || undefined ); } - queryStringToObject (str) { + queryStringToObject(str) { const query = Object.fromEntries( str .split('&') - .filter(str => str.includes('=')) - .map(str => str.split('=')) + .filter((str) => str.includes('=')) + .map((str) => str.split('=')) ); return query; } - objectToQueryString (query) { + objectToQueryString(query) { const str = Object.entries(query) - .map(arr => arr.join('=')) + .map((arr) => arr.join('=')) .join('&'); return str; } @@ -116,7 +113,7 @@ const CountDown = ({ until = moment() }) => { style={{ // fontVariant: 'none', fontSize: '1.6rem', - verticalAlign: 'center' + verticalAlign: 'center', // fontWeight: 400, }} > @@ -127,18 +124,16 @@ const CountDown = ({ until = moment() }) => { }; class App extends React.Component { - constructor (props) { + constructor(props) { super(props); - const router = new Router(router => {}); + const router = new Router((router) => {}); - let { - type = 'lm', - 'snapshot-source': network = networks.MAINNET - } = router.query; + let { type = 'lm', 'snapshot-source': network = networks.MAINNET } = + router.query; network = - Object.values(networks).find(n => n === network) || networks.MAINNET; + Object.values(networks).find((n) => n === network) || networks.MAINNET; const address = router.hashData; @@ -156,7 +151,7 @@ class App extends React.Component { usersVS: [], isLoadingLeaderboard: false, originalTitle: window.document.title, - router: router + router: router, }; if (this.state.network !== networks.MAINNET) { window.document.title = (window.document.title || '').replace( @@ -171,14 +166,14 @@ class App extends React.Component { this.updateAddress(this.state.address); } - updateWebsiteTitle () { + updateWebsiteTitle() { // window.document.title = `${this.state.type.toLowerCase()}/${this.state.address.slice( // 0, // 3 // )}..${this.state.address.slice(-12, -1)}`; } - getTimeIndex (time) { + getTimeIndex(time) { time = moment.utc(time); return ( Math.floor( @@ -187,13 +182,13 @@ class App extends React.Component { ); } - initDateTime () { + initDateTime() { const now = moment.utc(Date.now()); const currentTimeIndex = this.getTimeIndex(now); console.log({ currentTimeIndex }); this.setState( { - nowTimeIndex: currentTimeIndex + nowTimeIndex: currentTimeIndex, }, () => { this.updateTimestamp(currentTimeIndex); @@ -201,35 +196,35 @@ class App extends React.Component { ); } - componentDidMount () { - fetchUsers('lm', this.state.network).then(usersLM => + componentDidMount() { + fetchUsers('lm', this.state.network).then((usersLM) => this.setState({ usersLM }) ); - fetchUsers('vs', this.state.network).then(usersVS => + fetchUsers('vs', this.state.network).then((usersVS) => this.setState({ usersVS }) ); this.initDateTime(); } - updateNetwork (network) { + updateNetwork(network) { const router = this.state.router; router.push(router.hashData, { ...router.query, type: this.state.type, - 'snapshot-source': network + 'snapshot-source': network, }); window.location.reload(); this.setState({ - network + network, }); } - updateAddressEvent (event) { + updateAddressEvent(event) { const address = event.target.value; this.updateAddress(address); } - getRecentAddresses () { + getRecentAddresses() { try { let rtn = JSON.parse( window.localStorage.getItem(RECENT_ADDRESS_LIST_STORAGE_KEY) @@ -243,21 +238,21 @@ class App extends React.Component { } } - getRecentAddressesForCurrentType () { + getRecentAddressesForCurrentType() { let recents = this.getRecentAddresses(); let users = this.getUsersByType(this.state.type); - let currentTypeRecents = recents.filter(r => users.includes(r)); + let currentTypeRecents = recents.filter((r) => users.includes(r)); return currentTypeRecents; } - addRecentAddress (recentAddress) { + addRecentAddress(recentAddress) { if (!recentAddress || !recentAddress.startsWith('sif')) return; try { let addresses = [ - ...new Set([recentAddress, ...this.getRecentAddresses()]) + ...new Set([recentAddress, ...this.getRecentAddresses()]), ] - .filter(addr => typeof addr === 'string') - .map(addr => addr.trim()); + .filter((addr) => typeof addr === 'string') + .map((addr) => addr.trim()); return window.localStorage.setItem( RECENT_ADDRESS_LIST_STORAGE_KEY, JSON.stringify(addresses) @@ -267,11 +262,11 @@ class App extends React.Component { } } - updateAddress (address) { + updateAddress(address) { address = address ? address.trim() : address; this.state.router.push(address, { 'snapshot-source': this.state.network, - type: this.state.type + type: this.state.type, }); this.addRecentAddress(address); if (address !== 'leaderboard' && address !== undefined) { @@ -279,18 +274,18 @@ class App extends React.Component { address, this.state.type, this.state.network - ).then(userTimeSeriesData => + ).then((userTimeSeriesData) => this.setState({ userTimeSeriesData }, () => { fetchUserData( address, this.state.type, undefined, this.state.network - ).then(bulkUserData => { + ).then((bulkUserData) => { const userData = bulkUserData[this.state.timeIndex]; this.setState({ bulkUserData, - userData + userData, }); }); }) @@ -299,43 +294,40 @@ class App extends React.Component { this.setState({ address, userData: undefined, - userTimeSeriesData: undefined + userTimeSeriesData: undefined, }); } - updateTimestamp (timeIndex) { + updateTimestamp(timeIndex) { // because genesis block is included const minutes = timeIndex * 200; - const dateObj = moment - .utc(START_DATETIME) - .add(minutes, 'm') - .utc(); + const dateObj = moment.utc(START_DATETIME).add(minutes, 'm').utc(); const date = dateObj; this.setState({ date, timeIndex: +timeIndex, - userData: null + userData: null, }); console.log({ timeIndex }); const address = this.state.address; if (address && address.startsWith('sif')) { if (this.state.bulkUserData) { this.setState({ - userData: this.state.bulkUserData[timeIndex] + userData: this.state.bulkUserData[timeIndex], }); } } } - updateType (type) { + updateType(type) { this.state.router.push(this.state.router.hashData, { ...this.state.router.query, - type: type + type: type, }); const users = this.getUsersByType(type); this.setState( { - type + type, }, () => { this.updateAddress( @@ -347,17 +339,17 @@ class App extends React.Component { ); } - getUsersByType (type) { + getUsersByType(type) { return type === 'lm' ? this.state.usersLM : this.state.usersVS; } - render () { + render() { if (!this.state.usersLM || !this.state.usersVS) { return ( -
-
- -
+
+
+ +
); @@ -391,7 +383,7 @@ class App extends React.Component { addressInputRef.current.value = ''; }; - const clearInputIfAddressIncompatibile = nextType => { + const clearInputIfAddressIncompatibile = (nextType) => { if (!this.getUsersByType(nextType).includes(this.state.address)) { clearInput(); } @@ -406,25 +398,25 @@ class App extends React.Component { const isLoading = this.state.isLoadingLeaderboard || isLoadingUserData; return ( -
-
-
+
+
+
-
+
{this.state.network !== networks.MAINNET ? this.state.network : null}
{ + onClick={(e) => { this.updateType('lm'); clearInputIfAddressIncompatibile('lm'); }} @@ -435,7 +427,7 @@ class App extends React.Component { Liquidity Pool Mining Rewards
{ + onClick={(e) => { this.updateType('vs'); clearInputIfAddressIncompatibile('vs'); }} @@ -446,11 +438,11 @@ class App extends React.Component { Validator Staking & Delegating Rewards
-
-
-
+
+
+
{ + list="address-search" + name="address-search" + placeholder="Search or Select a Sif Address" + className="dropdown" + onChange={debounce((e) => { if (e.target.value !== this.state.address) { let isValid = users.includes(e.target.value); if (isValid) this.updateAddressEvent(e); } }, 500)} - onBlur={e => { + onBlur={(e) => { if (e.target.value !== this.state.address) { this.updateAddressEvent(e); } }} spellCheck={false} /> - - - {this.getRecentAddressesForCurrentType().map(user => ( + + + {this.getRecentAddressesForCurrentType().map((user) => ( ))} - {users.map(user => ( + {users.map((user) => ( ))} -
@@ -521,14 +516,14 @@ class App extends React.Component {
-
+
{this.state.address === 'leaderboard' && ( { + onLoadingStateChange={(state) => { if (state !== this.state.isLoadingLeaderboard) { this.setState({ - isLoadingLeaderboard: state + isLoadingLeaderboard: state, }); } }} @@ -542,7 +537,7 @@ class App extends React.Component { style={{ color: 'turquoise', width: '100%', - textAlign: 'center' + textAlign: 'center', }} > Loading Rewards... @@ -555,19 +550,19 @@ class App extends React.Component { {this.state.address !== 'leaderboard' && this.state.address !== undefined && timeSeriesData && ( -
+
+ onDoubleClick={(e) => this.updateTimestamp(this.state.nowTimeIndex) } style={{ width: '100%' }} - id='timestamp' - type='range' - min='0' + id="timestamp" + type="range" + min="0" max={timeSeriesData.length - 1} value={this.state.timeIndex} - onChange={e => this.updateTimestamp(e.target.value)} - step='1' + onChange={(e) => this.updateTimestamp(e.target.value)} + step="1" />
)} @@ -575,9 +570,9 @@ class App extends React.Component { this.state.address !== undefined && (
-
+
{this.state.timeIndex === this.state.nowTimeIndex ? ( ) : this.state.timeIndex === this.state.nowTimeIndex - 1 ? ( @@ -592,7 +587,7 @@ class App extends React.Component { 'Current Rewards' )}
-
+
{this.state.date.format( `ddd MMMM Do YYYY[,] [${this.state.date .clone() @@ -602,9 +597,9 @@ class App extends React.Component {
{this.state.date .clone() @@ -618,13 +613,10 @@ class App extends React.Component { ) + ' LOCAL'}
Now:{' '} - {moment() - .utc() - .format(`ddd MMMM Do YYYY hh:mm A`) + ' UTC '} + {moment().utc().format(`ddd MMMM Do YYYY hh:mm A`) + ' UTC '}
- {moment() - .local() - .format(`ddd MMMM Do YYYY hh:mm A`) + ' LOCAL'} + {moment().local().format(`ddd MMMM Do YYYY hh:mm A`) + + ' LOCAL'}
)} @@ -635,21 +627,21 @@ class App extends React.Component {
this.updateTimestamp(e.target.value)} - onInput={e => this.updateTimestamp(e.currentTarget.value)} - step='1' + onChange={(e) => this.updateTimestamp(e.target.value)} + onInput={(e) => this.updateTimestamp(e.currentTarget.value)} + step="1" />
)} @@ -669,7 +661,7 @@ class App extends React.Component { flexDirection: 'row', alignItems: 'stretch', justifyContent: 'center', - flexWrap: 'wrap' + flexWrap: 'wrap', }} > {' '} @@ -686,23 +678,23 @@ class App extends React.Component { return false; return { block, statNumVal }; }) - .filter(b => !!b) + .filter((b) => !!b) .map(({ block, statNumVal }) => { return (
-
+
{block.prefix} {block.data(statNumVal)} {block.suffix} @@ -715,11 +707,11 @@ class App extends React.Component { {this.state.address !== 'leaderboard' && this.state.address !== undefined ? ( -
+
JSON Metadata
@@ -729,30 +721,30 @@ class App extends React.Component { this.state.address !== undefined && (
{new Date(this.state.date.toISOString()).toString()}
)} {this.state.type === 'vs' ? ( -
+
Learn more about Sifchain Validator Staking & Delegation{' '} here .
) : ( -
+
Learn more about Sifchain Liquidity Pooling{' '} here @@ -760,13 +752,14 @@ class App extends React.Component {
)}
diff --git a/js/src/config.js b/js/src/config.js index 5db66eb..9099964 100644 --- a/js/src/config.js +++ b/js/src/config.js @@ -4,7 +4,7 @@ const config = { MAINNET: 'mainnet', DEVNET: 'devnet', TESTNET: 'testnet', - MAINNET_SNAPSHOTS_V2_BETA: 'mainnet_snapshots_v2_beta' + MAINNET_SNAPSHOTS_V2_BETA: 'snapshots_v2_mainnet' }, RECENT_ADDRESS_LIST_STORAGE_KEY: '__recent-address-list' }; From fb0a3a8f7a78e70594021bcfc65d3480df77c7cd Mon Sep 17 00:00:00 2001 From: McCall Alexander Date: Tue, 6 Jul 2021 12:55:59 -0600 Subject: [PATCH 4/5] updated frontend --- js/src/api.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/js/src/api.js b/js/src/api.js index 23bdea1..c8b19bd 100644 --- a/js/src/api.js +++ b/js/src/api.js @@ -13,28 +13,28 @@ const serverURL = (() => { } })(); -const getSnapshotNetworkHeaders = (network) => ({ - 'snapshot-source': network || networks.MAINNET, +const getSnapshotNetworkHeaders = network => ({ + 'snapshot-source': network || networks.MAINNET }); -function handleFailedRequest() { +function handleFailedRequest () { setTimeout(() => { window.location.reload(); }, 3000); } -const getUrl = (network) => { +const getUrl = network => { let url = serverURL; if (networks.MAINNET_SNAPSHOTS_V2_BETA === network) { - url = 'http://ec2-3-138-153-106.us-east-2.compute.amazonaws.com:3000/api'; + url = 'http://ec2-3-138-153-106.us-east-2.compute.amazonaws.com/api'; } return url; }; export const fetchUsers = (type, network) => { return window .fetch(`${getUrl(network)}/${type}?key=users`, { - headers: getSnapshotNetworkHeaders(network), + headers: getSnapshotNetworkHeaders(network) }) - .then((response) => response.json()) + .then(response => response.json()) .catch(handleFailedRequest); }; @@ -45,10 +45,10 @@ export const fetchUserData = (address, type, timestamp, network) => { timestamp ? `×tamp=${new Date(timestamp).toISOString()}` : `` }`, { - headers: getSnapshotNetworkHeaders(network), + headers: getSnapshotNetworkHeaders(network) } ) - .then((response) => response.json()) + .then(response => response.json()) .catch(handleFailedRequest); }; @@ -57,18 +57,18 @@ export const fetchUserTimeSeriesData = (address, type, network) => { .fetch( `${getUrl(network)}/${type}?key=userTimeSeriesData&address=${address}`, { - headers: getSnapshotNetworkHeaders(network), + headers: getSnapshotNetworkHeaders(network) } ) - .then((response) => response.json()) + .then(response => response.json()) .catch(handleFailedRequest); }; export const fetchStack = (type, network) => { return window .fetch(`${getUrl(network)}/${type}?key=stack`, { - headers: getSnapshotNetworkHeaders(network), + headers: getSnapshotNetworkHeaders(network) }) - .then((response) => response.json()) + .then(response => response.json()) .catch(handleFailedRequest); }; From ce52fe6f4f51d6530733642e7fd2e0a308abaa77 Mon Sep 17 00:00:00 2001 From: McCall Alexander Date: Tue, 6 Jul 2021 12:56:17 -0600 Subject: [PATCH 5/5] adding all --- js/server/config.js | 2 +- .../loaders/loadLiquidityMinersSnapshot.js | 14 +- js/server/main.js | 20 +- js/server/process.js | 37 +-- js/src/App.js | 282 +++++++++--------- 5 files changed, 183 insertions(+), 172 deletions(-) diff --git a/js/server/config.js b/js/server/config.js index d818c47..7f7f616 100644 --- a/js/server/config.js +++ b/js/server/config.js @@ -39,7 +39,7 @@ const config = { DEPOSITS_ALLOWED_DURATION_MS, MULTIPLIER_MATURITY: 864, // 4 months in in 200minute intervals, NUMBER_OF_INTERVALS_TO_RUN: REWARD_ACCRUAL_DURATION_INTERVAL_COUNT + 864, // duration of bucket drain + duration to latest possible multiplier maturity - REWARD_ACCRUAL_DURATION_INTERVAL_COUNT, + REWARD_ACCRUAL_DURATION_INTERVAL_COUNT }; module.exports = config; diff --git a/js/server/loaders/loadLiquidityMinersSnapshot.js b/js/server/loaders/loadLiquidityMinersSnapshot.js index 0721590..231a70a 100644 --- a/js/server/loaders/loadLiquidityMinersSnapshot.js +++ b/js/server/loaders/loadLiquidityMinersSnapshot.js @@ -46,11 +46,11 @@ const { getDatabase } = require('./getDatabase'); // } // }; -const getSQLQueryByNetwork = (network) => { +const getSQLQueryByNetwork = network => { network = network ? network.toLowerCase() : network; switch (network) { case TESTNET: { - return getDatabase().transaction(async (tx) => { + return getDatabase().transaction(async tx => { const snapshots_new = await tx.many( slonik.sql`select snapshot_data from snapshots_new_dev ORDER BY created_at DESC LIMIT 1` ); @@ -64,13 +64,13 @@ const getSQLQueryByNetwork = (network) => { data: { snapshots_new, snapshots_lm_claims, - snapshots_lm_dispensation, - }, + snapshots_lm_dispensation + } }; }); } default: { - return getDatabase().transaction(async (tx) => { + return getDatabase().transaction(async tx => { const snapshots_new = tx.many( slonik.sql`select * from snapshots_lm_rf rf where rf.snapshot_time = (select max(snapshot_time) from snapshots_lm_rf)` ); @@ -92,8 +92,8 @@ const getSQLQueryByNetwork = (network) => { data: { snapshots_new: snapshotsNewLoaded, snapshots_lm_claims: await snapshots_lm_claims, - snapshots_lm_dispensation: await snapshots_lm_dispensation, - }, + snapshots_lm_dispensation: await snapshots_lm_dispensation + } }; }); } diff --git a/js/server/main.js b/js/server/main.js index a01185f..8acbdd1 100644 --- a/js/server/main.js +++ b/js/server/main.js @@ -8,23 +8,25 @@ const { ProcessingHandler } = require('./worker'); const { DEVNET, MAINNET, - TESTNET, + TESTNET } = require('./constants/snapshot-source-names'); const { GET_LM_DISPENSATION_JOB, - GET_VS_DISPENSATION_JOB, + GET_VS_DISPENSATION_JOB } = require('./constants/action-names'); const moment = require('moment'); const { encrypt, decrypt } = require('./util/encrypt'); const { - createGenericDispensationJob, + createGenericDispensationJob } = require('./util/createGenericDispensationJob'); if (process.env.DATABASE_URL) { const encrypted = encrypt(process.env.DATABASE_URL); require('fs').writeFileSync('./DATABASE_URL.enc', encrypted.encryptedData); } else { - const dburlEnc = require('fs').readFileSync('./DATABASE_URL.enc').toString(); + const dburlEnc = require('fs') + .readFileSync('./DATABASE_URL.enc') + .toString(); const data = decrypt(dburlEnc); process.env.DATABASE_URL = data; } @@ -61,12 +63,12 @@ let createTestnetHandler = () => { }; const processingHandlers = { [MAINNET]: ProcessingHandler.init(MAINNET), - get [DEVNET]() { + get [DEVNET] () { return createTestnetHandler(); }, - get [TESTNET]() { + get [TESTNET] () { return createTestnetHandler(); - }, + } }; // const processingHandler = BackgroundProcessor.startAsMainProcess(); @@ -164,7 +166,7 @@ app.get('/api/lm', async (req, res, next) => { const timeIndex = getTimeIndex(req.query.timestamp); responseJSON = await processingHandler.dispatch('GET_LM_USER_DATA', { address, - timeIndex, + timeIndex }); break; } @@ -226,7 +228,7 @@ app.get('/api/vs', async (req, res, next) => { const timeIndex = getTimeIndex(req.query.timestamp); responseJSON = await processingHandler.dispatch('GET_VS_USER_DATA', { address, - timeIndex, + timeIndex }); break; } diff --git a/js/server/process.js b/js/server/process.js index 9a5f5c6..6b9d0e6 100644 --- a/js/server/process.js +++ b/js/server/process.js @@ -3,41 +3,42 @@ const { remapLMAddresses, getLMTimeseriesFinalIndex, createClaimEvents, - createDispensationEvents, + createDispensationEvents } = require('./util/lm-util'); const { remapVSAddresses, - getVSTimeseriesFinalIndex, + getVSTimeseriesFinalIndex } = require('./util/vs-util'); const { processVSGlobalState } = require('./process-vs'); const { EVENT_INTERVAL_MINUTES, - NUMBER_OF_INTERVALS_TO_RUN, + NUMBER_OF_INTERVALS_TO_RUN } = require('./config'); const { GlobalTimestampState } = require('./types'); const { VALIDATOR_STAKING, - LIQUIDITY_MINING, + LIQUIDITY_MINING } = require('./constants/reward-program-types'); const { mockMinerClaims, mockMinerDispensations } = require('./mock'); -exports.getProcessedLMData = (snapshotLM) => { +exports.getProcessedLMData = snapshotLM => { let { snapshots_new: [{ snapshot_data: minerSnapshotData }], snapshots_lm_claims: [{ snapshot_data: claimsSnapshotData = {} } = {}], snapshots_lm_dispensation: [ - { snapshot_data: dispensationsSnapshotData = {} } = {}, - ] = [], + { snapshot_data: dispensationsSnapshotData = {} } = {} + ] = [] } = snapshotLM.data; - const snapshotTimeseriesFinalIndex = - getLMTimeseriesFinalIndex(minerSnapshotData); + const snapshotTimeseriesFinalIndex = getLMTimeseriesFinalIndex( + minerSnapshotData + ); if (process.env.MOCK_DATA_ENABLED === 'true') { claimsSnapshotData = mockMinerClaims(snapshotLM).claimsSnapshotData; - dispensationsSnapshotData = - mockMinerDispensations(claimsSnapshotData).dispensationsSnapshotData; + dispensationsSnapshotData = mockMinerDispensations(claimsSnapshotData) + .dispensationsSnapshotData; } const claimEventsByUserByTimestamp = createClaimEvents(claimsSnapshotData); @@ -57,13 +58,13 @@ exports.getProcessedLMData = (snapshotLM) => { ); }; -exports.getProcessedVSData = (snapshotVS) => { +exports.getProcessedVSData = snapshotVS => { let { snapshots_validators: [{ snapshot_data: validatorSnapshotData }], snapshots_vs_claims: [{ snapshot_data: claimsSnapshotData = {} } = {}], snapshots_vs_dispensation: [ - { snapshot_data: dispensationsSnapshotData = {} } = {}, - ] = [], + { snapshot_data: dispensationsSnapshotData = {} } = {} + ] = [] } = snapshotVS.data; const snapshotTimeseriesFinalIndex = getVSTimeseriesFinalIndex( @@ -78,7 +79,7 @@ exports.getProcessedVSData = (snapshotVS) => { console.time('remapVS'); const { userEventsByTimestamp } = remapVSAddresses(validatorSnapshotData); console.timeEnd('remapVS'); - function getCurrentCommissionRate(validatorStakeAddress, stateIndex) { + function getCurrentCommissionRate (validatorStakeAddress, stateIndex) { const validatorCommissionData = validatorSnapshotData[validatorStakeAddress].commission; const commissionIndex = @@ -101,10 +102,10 @@ exports.getProcessedVSData = (snapshotVS) => { const cacheEnabled = false; const history = { [VALIDATOR_STAKING]: {}, - [LIQUIDITY_MINING]: {}, + [LIQUIDITY_MINING]: {} }; -function processUserEventsByTimestamp( +function processUserEventsByTimestamp ( userEventsByTimestamp, getCurrentCommissionRate = (address, stateIndex) => 0, rewardProgramType, @@ -134,7 +135,7 @@ function processUserEventsByTimestamp( lastGlobalState, timestamp, userEvents, - (address) => getCurrentCommissionRate(address, i), + address => getCurrentCommissionRate(address, i), rewardProgramType, isSimulatedFutureInterval, claimEventsByUser, diff --git a/js/src/App.js b/js/src/App.js index 2a1a167..81dbb99 100644 --- a/js/src/App.js +++ b/js/src/App.js @@ -1,7 +1,7 @@ import { START_DATETIME, networks, - RECENT_ADDRESS_LIST_STORAGE_KEY, + RECENT_ADDRESS_LIST_STORAGE_KEY } from './config'; import './App.css'; import React, { useEffect, useMemo, useState } from 'react'; @@ -15,8 +15,8 @@ import { StatBlocks } from './StatBlocks'; import { UserDataSummary } from './UserDataSummary'; // show all fields locally -const SHOULD_HIDE_NON_USER_FRIENDLY_FIELDS = - !!process.env.REACT_APP_DEPLOYMENT_TAG; +const SHOULD_HIDE_NON_USER_FRIENDLY_FIELDS = !!process.env + .REACT_APP_DEPLOYMENT_TAG; const userFieldsToHide = [ 'reservedReward', @@ -26,7 +26,7 @@ const userFieldsToHide = [ 'nextReward', 'nextRewardProjectedFutureReward', 'yearsToMaturity', - 'currentAPYOnTickets', + 'currentAPYOnTickets' ]; const debounce = (fn, ms) => { @@ -40,7 +40,7 @@ const debounce = (fn, ms) => { }; class Router { - constructor(onChange = (router) => {}) { + constructor (onChange = router => {}) { this.query = {}; this.hashData = undefined; this.evaluateHashQueryAndData(); @@ -48,12 +48,12 @@ class Router { this.onChange = onChange; } - evaluateHashQueryAndData() { + evaluateHashQueryAndData () { this.query = this.queryStringToObject(window.location.hash); this.hashData = this.extractHashData(); } - push(hash, queryObject) { + push (hash, queryObject) { const queryStr = this.objectToQueryString(queryObject); console.log(queryStr, queryObject); window.history.pushState(undefined, '', `#${hash || ''}&${queryStr}`); @@ -61,25 +61,28 @@ class Router { // this.onChange(this); } - extractHashData() { + extractHashData () { return ( - (window.location.hash || '').substr(1).split('&').shift() || undefined + (window.location.hash || '') + .substr(1) + .split('&') + .shift() || undefined ); } - queryStringToObject(str) { + queryStringToObject (str) { const query = Object.fromEntries( str .split('&') - .filter((str) => str.includes('=')) - .map((str) => str.split('=')) + .filter(str => str.includes('=')) + .map(str => str.split('=')) ); return query; } - objectToQueryString(query) { + objectToQueryString (query) { const str = Object.entries(query) - .map((arr) => arr.join('=')) + .map(arr => arr.join('=')) .join('&'); return str; } @@ -113,7 +116,7 @@ const CountDown = ({ until = moment() }) => { style={{ // fontVariant: 'none', fontSize: '1.6rem', - verticalAlign: 'center', + verticalAlign: 'center' // fontWeight: 400, }} > @@ -124,16 +127,18 @@ const CountDown = ({ until = moment() }) => { }; class App extends React.Component { - constructor(props) { + constructor (props) { super(props); - const router = new Router((router) => {}); + const router = new Router(router => {}); - let { type = 'lm', 'snapshot-source': network = networks.MAINNET } = - router.query; + let { + type = 'lm', + 'snapshot-source': network = networks.MAINNET + } = router.query; network = - Object.values(networks).find((n) => n === network) || networks.MAINNET; + Object.values(networks).find(n => n === network) || networks.MAINNET; const address = router.hashData; @@ -151,7 +156,7 @@ class App extends React.Component { usersVS: [], isLoadingLeaderboard: false, originalTitle: window.document.title, - router: router, + router: router }; if (this.state.network !== networks.MAINNET) { window.document.title = (window.document.title || '').replace( @@ -166,14 +171,14 @@ class App extends React.Component { this.updateAddress(this.state.address); } - updateWebsiteTitle() { + updateWebsiteTitle () { // window.document.title = `${this.state.type.toLowerCase()}/${this.state.address.slice( // 0, // 3 // )}..${this.state.address.slice(-12, -1)}`; } - getTimeIndex(time) { + getTimeIndex (time) { time = moment.utc(time); return ( Math.floor( @@ -182,13 +187,13 @@ class App extends React.Component { ); } - initDateTime() { + initDateTime () { const now = moment.utc(Date.now()); const currentTimeIndex = this.getTimeIndex(now); console.log({ currentTimeIndex }); this.setState( { - nowTimeIndex: currentTimeIndex, + nowTimeIndex: currentTimeIndex }, () => { this.updateTimestamp(currentTimeIndex); @@ -196,35 +201,35 @@ class App extends React.Component { ); } - componentDidMount() { - fetchUsers('lm', this.state.network).then((usersLM) => + componentDidMount () { + fetchUsers('lm', this.state.network).then(usersLM => this.setState({ usersLM }) ); - fetchUsers('vs', this.state.network).then((usersVS) => + fetchUsers('vs', this.state.network).then(usersVS => this.setState({ usersVS }) ); this.initDateTime(); } - updateNetwork(network) { + updateNetwork (network) { const router = this.state.router; router.push(router.hashData, { ...router.query, type: this.state.type, - 'snapshot-source': network, + 'snapshot-source': network }); window.location.reload(); this.setState({ - network, + network }); } - updateAddressEvent(event) { + updateAddressEvent (event) { const address = event.target.value; this.updateAddress(address); } - getRecentAddresses() { + getRecentAddresses () { try { let rtn = JSON.parse( window.localStorage.getItem(RECENT_ADDRESS_LIST_STORAGE_KEY) @@ -238,21 +243,21 @@ class App extends React.Component { } } - getRecentAddressesForCurrentType() { + getRecentAddressesForCurrentType () { let recents = this.getRecentAddresses(); let users = this.getUsersByType(this.state.type); - let currentTypeRecents = recents.filter((r) => users.includes(r)); + let currentTypeRecents = recents.filter(r => users.includes(r)); return currentTypeRecents; } - addRecentAddress(recentAddress) { + addRecentAddress (recentAddress) { if (!recentAddress || !recentAddress.startsWith('sif')) return; try { let addresses = [ - ...new Set([recentAddress, ...this.getRecentAddresses()]), + ...new Set([recentAddress, ...this.getRecentAddresses()]) ] - .filter((addr) => typeof addr === 'string') - .map((addr) => addr.trim()); + .filter(addr => typeof addr === 'string') + .map(addr => addr.trim()); return window.localStorage.setItem( RECENT_ADDRESS_LIST_STORAGE_KEY, JSON.stringify(addresses) @@ -262,11 +267,11 @@ class App extends React.Component { } } - updateAddress(address) { + updateAddress (address) { address = address ? address.trim() : address; this.state.router.push(address, { 'snapshot-source': this.state.network, - type: this.state.type, + type: this.state.type }); this.addRecentAddress(address); if (address !== 'leaderboard' && address !== undefined) { @@ -274,18 +279,18 @@ class App extends React.Component { address, this.state.type, this.state.network - ).then((userTimeSeriesData) => + ).then(userTimeSeriesData => this.setState({ userTimeSeriesData }, () => { fetchUserData( address, this.state.type, undefined, this.state.network - ).then((bulkUserData) => { + ).then(bulkUserData => { const userData = bulkUserData[this.state.timeIndex]; this.setState({ bulkUserData, - userData, + userData }); }); }) @@ -294,40 +299,43 @@ class App extends React.Component { this.setState({ address, userData: undefined, - userTimeSeriesData: undefined, + userTimeSeriesData: undefined }); } - updateTimestamp(timeIndex) { + updateTimestamp (timeIndex) { // because genesis block is included const minutes = timeIndex * 200; - const dateObj = moment.utc(START_DATETIME).add(minutes, 'm').utc(); + const dateObj = moment + .utc(START_DATETIME) + .add(minutes, 'm') + .utc(); const date = dateObj; this.setState({ date, timeIndex: +timeIndex, - userData: null, + userData: null }); console.log({ timeIndex }); const address = this.state.address; if (address && address.startsWith('sif')) { if (this.state.bulkUserData) { this.setState({ - userData: this.state.bulkUserData[timeIndex], + userData: this.state.bulkUserData[timeIndex] }); } } } - updateType(type) { + updateType (type) { this.state.router.push(this.state.router.hashData, { ...this.state.router.query, - type: type, + type: type }); const users = this.getUsersByType(type); this.setState( { - type, + type }, () => { this.updateAddress( @@ -339,17 +347,17 @@ class App extends React.Component { ); } - getUsersByType(type) { + getUsersByType (type) { return type === 'lm' ? this.state.usersLM : this.state.usersVS; } - render() { + render () { if (!this.state.usersLM || !this.state.usersVS) { return ( -
-
- -
+
+
+ +
); @@ -383,7 +391,7 @@ class App extends React.Component { addressInputRef.current.value = ''; }; - const clearInputIfAddressIncompatibile = (nextType) => { + const clearInputIfAddressIncompatibile = nextType => { if (!this.getUsersByType(nextType).includes(this.state.address)) { clearInput(); } @@ -398,25 +406,25 @@ class App extends React.Component { const isLoading = this.state.isLoadingLeaderboard || isLoadingUserData; return ( -
-
-
+
+
+
-
+
{this.state.network !== networks.MAINNET ? this.state.network : null}
{ + onClick={e => { this.updateType('lm'); clearInputIfAddressIncompatibile('lm'); }} @@ -427,7 +435,7 @@ class App extends React.Component { Liquidity Pool Mining Rewards
{ + onClick={e => { this.updateType('vs'); clearInputIfAddressIncompatibile('vs'); }} @@ -438,11 +446,11 @@ class App extends React.Component { Validator Staking & Delegating Rewards
-
-
-
+
+
+
{ + list='address-search' + name='address-search' + placeholder='Search or Select a Sif Address' + className='dropdown' + onChange={debounce(e => { if (e.target.value !== this.state.address) { let isValid = users.includes(e.target.value); if (isValid) this.updateAddressEvent(e); } }, 500)} - onBlur={(e) => { + onBlur={e => { if (e.target.value !== this.state.address) { this.updateAddressEvent(e); } }} spellCheck={false} /> - - - {this.getRecentAddressesForCurrentType().map((user) => ( + + + {this.getRecentAddressesForCurrentType().map(user => ( ))} - {users.map((user) => ( + {users.map(user => ( ))} -
@@ -516,14 +521,14 @@ class App extends React.Component {
-
+
{this.state.address === 'leaderboard' && ( { + onLoadingStateChange={state => { if (state !== this.state.isLoadingLeaderboard) { this.setState({ - isLoadingLeaderboard: state, + isLoadingLeaderboard: state }); } }} @@ -537,7 +542,7 @@ class App extends React.Component { style={{ color: 'turquoise', width: '100%', - textAlign: 'center', + textAlign: 'center' }} > Loading Rewards... @@ -550,19 +555,19 @@ class App extends React.Component { {this.state.address !== 'leaderboard' && this.state.address !== undefined && timeSeriesData && ( -
+
+ onDoubleClick={e => this.updateTimestamp(this.state.nowTimeIndex) } style={{ width: '100%' }} - id="timestamp" - type="range" - min="0" + id='timestamp' + type='range' + min='0' max={timeSeriesData.length - 1} value={this.state.timeIndex} - onChange={(e) => this.updateTimestamp(e.target.value)} - step="1" + onChange={e => this.updateTimestamp(e.target.value)} + step='1' />
)} @@ -570,9 +575,9 @@ class App extends React.Component { this.state.address !== undefined && (
-
+
{this.state.timeIndex === this.state.nowTimeIndex ? ( ) : this.state.timeIndex === this.state.nowTimeIndex - 1 ? ( @@ -587,7 +592,7 @@ class App extends React.Component { 'Current Rewards' )}
-
+
{this.state.date.format( `ddd MMMM Do YYYY[,] [${this.state.date .clone() @@ -597,9 +602,9 @@ class App extends React.Component {
{this.state.date .clone() @@ -613,10 +618,13 @@ class App extends React.Component { ) + ' LOCAL'}
Now:{' '} - {moment().utc().format(`ddd MMMM Do YYYY hh:mm A`) + ' UTC '} + {moment() + .utc() + .format(`ddd MMMM Do YYYY hh:mm A`) + ' UTC '}
- {moment().local().format(`ddd MMMM Do YYYY hh:mm A`) + - ' LOCAL'} + {moment() + .local() + .format(`ddd MMMM Do YYYY hh:mm A`) + ' LOCAL'}
)} @@ -627,21 +635,21 @@ class App extends React.Component {
this.updateTimestamp(e.target.value)} - onInput={(e) => this.updateTimestamp(e.currentTarget.value)} - step="1" + onChange={e => this.updateTimestamp(e.target.value)} + onInput={e => this.updateTimestamp(e.currentTarget.value)} + step='1' />
)} @@ -661,7 +669,7 @@ class App extends React.Component { flexDirection: 'row', alignItems: 'stretch', justifyContent: 'center', - flexWrap: 'wrap', + flexWrap: 'wrap' }} > {' '} @@ -678,23 +686,23 @@ class App extends React.Component { return false; return { block, statNumVal }; }) - .filter((b) => !!b) + .filter(b => !!b) .map(({ block, statNumVal }) => { return (
-
+
{block.prefix} {block.data(statNumVal)} {block.suffix} @@ -707,11 +715,11 @@ class App extends React.Component { {this.state.address !== 'leaderboard' && this.state.address !== undefined ? ( -
+
JSON Metadata
@@ -721,30 +729,30 @@ class App extends React.Component { this.state.address !== undefined && (
{new Date(this.state.date.toISOString()).toString()}
)} {this.state.type === 'vs' ? ( -
+
Learn more about Sifchain Validator Staking & Delegation{' '} here .
) : ( -
+
Learn more about Sifchain Liquidity Pooling{' '} here @@ -752,9 +760,9 @@ class App extends React.Component {
)}