diff --git a/docker-compose.yml b/docker-compose.yml
index 58d1ea7f..53899562 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,24 +15,6 @@ services:
volumes:
- /nano:/root
- nano-node-monitor:
- image: nanotools/nanonodemonitor
- container_name: nano-node-monitor
- hostname: nano-node-monitor
- restart: unless-stopped
- volumes:
- - ./nano-node-monitor:/opt/nanoNodeMonitor
- ports:
- - "80:80"
-
- watchtower:
- image: v2tec/watchtower
- container_name: watchtower
- restart: unless-stopped
- command: watchtower nano-node nano-node-monitor
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock
-
networks:
default:
external:
diff --git a/package-lock.json b/package-lock.json
index 4da268b4..d0e92443 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,7 +13,7 @@
"@sentry/node": "^6.19.2",
"antd": "^5.5.0",
"bignumber.js": "^9.0.0",
- "body-parser": "^1.19.0",
+ "body-parser": "^1.20.2",
"cors": "^2.8.5",
"dot-object": "^2.1.4",
"dotenv": "^8.2.0",
@@ -49,14 +49,14 @@
"react-responsive": "^9.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
- "reconnecting-websocket": "^4.4.0",
- "redis": "^3.1.2",
+ "redis": "^4.6.13",
"remark-gfm": "^3.0.1",
"rimraf": "^3.0.2",
"saslprep": "^1.0.3",
"source-map-explorer": "^2.5.2",
"timeago-react": "^3.0.0",
"use-deep-compare-effect": "^1.8.1",
+ "websocket-reconnect": "^1.0.10",
"ws": "^7.5.7",
"yargs": "^16.2.0"
},
@@ -4095,6 +4095,59 @@
"react-dom": "^17.0.1"
}
},
+ "node_modules/@redis/bloom": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
+ "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/client": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz",
+ "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==",
+ "dependencies": {
+ "cluster-key-slot": "1.1.2",
+ "generic-pool": "3.9.0",
+ "yallist": "4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@redis/graph": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
+ "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/json": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz",
+ "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/search": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz",
+ "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/time-series": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz",
+ "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
"node_modules/@rushstack/eslint-patch": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
@@ -7295,12 +7348,12 @@
"integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ=="
},
"node_modules/body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
+ "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"dependencies": {
"bytes": "3.1.2",
- "content-type": "~1.0.4",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@@ -7308,7 +7361,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
- "raw-body": "2.5.1",
+ "raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@@ -7809,6 +7862,14 @@
"node": ">=0.8"
}
},
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
+ "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -8008,9 +8069,9 @@
]
},
"node_modules/content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"engines": {
"node": ">= 0.6"
}
@@ -9046,14 +9107,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/denque": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
- "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==",
- "engines": {
- "node": ">=0.10"
- }
- },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -10589,6 +10642,29 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/express/node_modules/body-parser": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+ "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
"node_modules/express/node_modules/cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
@@ -10610,6 +10686,20 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/express/node_modules/raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/express/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -11388,6 +11478,14 @@
"node": ">=12"
}
},
+ "node_modules/generic-pool": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
+ "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -19680,9 +19778,9 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@@ -20867,11 +20965,6 @@
"node": ">=8.10.0"
}
},
- "node_modules/reconnecting-websocket": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz",
- "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="
- },
"node_modules/recursive-readdir": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
@@ -20897,45 +20990,16 @@
}
},
"node_modules/redis": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
- "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
- "dependencies": {
- "denque": "^1.5.0",
- "redis-commands": "^1.7.0",
- "redis-errors": "^1.2.0",
- "redis-parser": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-redis"
- }
- },
- "node_modules/redis-commands": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
- "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
- },
- "node_modules/redis-errors": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
- "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/redis-parser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
- "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
+ "version": "4.6.13",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz",
+ "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==",
"dependencies": {
- "redis-errors": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
+ "@redis/bloom": "1.2.0",
+ "@redis/client": "1.5.14",
+ "@redis/graph": "1.1.1",
+ "@redis/json": "1.0.6",
+ "@redis/search": "1.1.6",
+ "@redis/time-series": "1.0.5"
}
},
"node_modules/redux": {
@@ -24131,6 +24195,35 @@
"node": ">=0.8.0"
}
},
+ "node_modules/websocket-reconnect": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/websocket-reconnect/-/websocket-reconnect-1.0.10.tgz",
+ "integrity": "sha512-XKOLCZ1vTey+VuljMzVEIKrfbO/bpslJDl2bH7mUZsraXbV9qfqgQGvgUeBF89NReIUpimmpIIi0dwBQEvFhJQ==",
+ "dependencies": {
+ "events": "^3.3.0",
+ "ws": "^8.11.0"
+ }
+ },
+ "node_modules/websocket-reconnect/node_modules/ws": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
+ "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/whatwg-encoding": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
@@ -27672,6 +27765,46 @@
"integrity": "sha512-7PGLWa9MZ5x/cWy8EH2VzI4T8q5WpuHbixzCDXqixP/WyqwIrg5NDUPgYuFnB4IEIZF+6nA265mYzswFo/h1Pw==",
"requires": {}
},
+ "@redis/bloom": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
+ "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
+ "requires": {}
+ },
+ "@redis/client": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz",
+ "integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==",
+ "requires": {
+ "cluster-key-slot": "1.1.2",
+ "generic-pool": "3.9.0",
+ "yallist": "4.0.0"
+ }
+ },
+ "@redis/graph": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
+ "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
+ "requires": {}
+ },
+ "@redis/json": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz",
+ "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==",
+ "requires": {}
+ },
+ "@redis/search": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz",
+ "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==",
+ "requires": {}
+ },
+ "@redis/time-series": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz",
+ "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==",
+ "requires": {}
+ },
"@rushstack/eslint-patch": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
@@ -30163,12 +30296,12 @@
"integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ=="
},
"body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
+ "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"requires": {
"bytes": "3.1.2",
- "content-type": "~1.0.4",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@@ -30176,7 +30309,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
- "raw-body": "2.5.1",
+ "raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@@ -30542,6 +30675,11 @@
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
},
+ "cluster-key-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
+ "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="
+ },
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -30696,9 +30834,9 @@
}
},
"content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="
},
"continuation-local-storage": {
"version": "3.2.1",
@@ -31424,11 +31562,6 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
- "denque": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
- "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw=="
- },
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -32555,6 +32688,25 @@
"vary": "~1.1.2"
},
"dependencies": {
+ "body-parser": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
+ "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "requires": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.11.0",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ }
+ },
"cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
@@ -32573,6 +32725,17 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "requires": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -33145,6 +33308,11 @@
"json-bigint": "^1.0.0"
}
},
+ "generic-pool": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
+ "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g=="
+ },
"gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -38876,9 +39044,9 @@
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"requires": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@@ -39721,11 +39889,6 @@
"picomatch": "^2.2.1"
}
},
- "reconnecting-websocket": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz",
- "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="
- },
"recursive-readdir": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
@@ -39745,32 +39908,16 @@
}
},
"redis": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
- "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
+ "version": "4.6.13",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz",
+ "integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==",
"requires": {
- "denque": "^1.5.0",
- "redis-commands": "^1.7.0",
- "redis-errors": "^1.2.0",
- "redis-parser": "^3.0.0"
- }
- },
- "redis-commands": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
- "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
- },
- "redis-errors": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
- "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="
- },
- "redis-parser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
- "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
- "requires": {
- "redis-errors": "^1.0.0"
+ "@redis/bloom": "1.2.0",
+ "@redis/client": "1.5.14",
+ "@redis/graph": "1.1.1",
+ "@redis/json": "1.0.6",
+ "@redis/search": "1.1.6",
+ "@redis/time-series": "1.0.5"
}
},
"redux": {
@@ -42135,6 +42282,23 @@
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
},
+ "websocket-reconnect": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/websocket-reconnect/-/websocket-reconnect-1.0.10.tgz",
+ "integrity": "sha512-XKOLCZ1vTey+VuljMzVEIKrfbO/bpslJDl2bH7mUZsraXbV9qfqgQGvgUeBF89NReIUpimmpIIi0dwBQEvFhJQ==",
+ "requires": {
+ "events": "^3.3.0",
+ "ws": "^8.11.0"
+ },
+ "dependencies": {
+ "ws": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
+ "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
+ "requires": {}
+ }
+ }
+ },
"whatwg-encoding": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
diff --git a/package.json b/package.json
index 069b7f0f..acb7bf6a 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"@sentry/node": "^6.19.2",
"antd": "^5.5.0",
"bignumber.js": "^9.0.0",
- "body-parser": "^1.19.0",
+ "body-parser": "^1.20.2",
"cors": "^2.8.5",
"dot-object": "^2.1.4",
"dotenv": "^8.2.0",
@@ -78,14 +78,14 @@
"react-responsive": "^9.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
- "reconnecting-websocket": "^4.4.0",
- "redis": "^3.1.2",
+ "redis": "^4.6.13",
"remark-gfm": "^3.0.1",
"rimraf": "^3.0.2",
"saslprep": "^1.0.3",
"source-map-explorer": "^2.5.2",
"timeago-react": "^3.0.0",
"use-deep-compare-effect": "^1.8.1",
+ "websocket-reconnect": "^1.0.10",
"ws": "^7.5.7",
"yargs": "^16.2.0"
},
diff --git a/server/api/delegators.js b/server/api/delegators.js
index 2d1bc0c4..a4125b5a 100644
--- a/server/api/delegators.js
+++ b/server/api/delegators.js
@@ -1,15 +1,14 @@
-const { client: redisClient } = require("../client/redis");
+const { redisClient } = require("../client/redis");
const { Sentry } = require("../sentry");
const { DELEGATORS } = require("../constants");
const PER_PAGE = 50;
const getTotal = account =>
- new Promise(async resolve => {
- redisClient.zcard(`DELEGATORS:${account}`, (err, total) => {
- if (err) Sentry.captureException(err);
- resolve(total);
- });
+ new Promise(async () => {
+ const [total] = await redisClient.zCard(`DELEGATORS:${account}`);
+
+ console.log("~~~~~total", total);
});
const getDelegatorsPage = async ({ page = 1, account }) =>
@@ -44,33 +43,41 @@ const getDelegatorsPage = async ({ page = 1, account }) =>
});
const getAllDelegatorsCount = async () =>
- new Promise(async resolve => {
- redisClient.keys(`${DELEGATORS}:*`, (err, res) => {
- if (err) {
- Sentry.captureException(err);
- return;
- }
+ async function findKeys(pattern) {
+ let cursor = "0";
+ let keys = [];
- Promise.all(
- res.map(async key => {
- const account = key.replace(`${DELEGATORS}:`, "");
- const count = await getTotal(account);
+ do {
+ const reply = await redisClient.scan(cursor, "MATCH", pattern, "COUNT", "100");
+ keys.push(...reply.keys);
+ } while (cursor !== "0");
- return {
- [account]: count,
- };
- }),
- ).then(result => {
- resolve(
- result.reduce((acc, value) => {
- const key = Object.keys(value)[0];
- acc[key] = value[key];
- return acc;
- }, {}),
- );
- });
- });
+ return keys;
+ };
+new Promise(async resolve => {
+ const delegators = await redisClient
+ .findKeys(`${DELEGATORS}:*`)
+ .filter(key => key.startsWith(`${DELEGATORS}`));
+
+ Promise.all(
+ res.map(async key => {
+ const account = key.replace(`${DELEGATORS}:`, "");
+ const count = await getTotal(account);
+
+ return {
+ [account]: count,
+ };
+ }),
+ ).then(result => {
+ resolve(
+ result.reduce((acc, value) => {
+ const key = Object.keys(value)[0];
+ acc[key] = value[key];
+ return acc;
+ }, {}),
+ );
});
+});
module.exports = {
getDelegatorsPage,
diff --git a/server/api/developerFundTransactions.js b/server/api/developerFundTransactions.js
index b3854bf0..08823a85 100644
--- a/server/api/developerFundTransactions.js
+++ b/server/api/developerFundTransactions.js
@@ -23,11 +23,13 @@ const getDeveloperFundTransactions = async () => {
count: "-1",
});
- const history = res.history
- .map(({ type, height, ...rest }) =>
- type === "send" ? { origin: account, type, ...rest } : undefined,
- )
- .filter(Boolean);
+ const { history = [] } =
+ res |
+ {}
+ .map(({ type, height, ...rest }) =>
+ type === "send" ? { origin: account, type, ...rest } : undefined,
+ )
+ .filter(Boolean);
accountsHistory = accountsHistory.concat(history);
diff --git a/server/api/richList.js b/server/api/richList.js
index 75ad2217..1b1d95ec 100644
--- a/server/api/richList.js
+++ b/server/api/richList.js
@@ -1,23 +1,25 @@
-const { client: redisClient } = require("../client/redis");
+const { redisClient } = require("../client/redis");
const { Sentry } = require("../sentry");
const { REDIS_RICH_LIST } = require("../constants");
const PER_PAGE = 25;
-const getTotal = () =>
- new Promise(async resolve => {
- redisClient.zcard(REDIS_RICH_LIST, (err, total) => {
- if (err) Sentry.captureException(err);
- resolve(total);
- });
- });
+const { NL_REDIS_DB_INDEX } = process.env;
+
+const getTotal = async () => {
+ const total = await redisClient.zCard(REDIS_RICH_LIST);
+
+ console.log("~~~~total", total);
+ return total;
+};
const getRichListPage = async (page = 1) =>
new Promise(async resolve => {
+ await redisClient.select(NL_REDIS_DB_INDEX);
const offset = (page - 1) * PER_PAGE;
const total = await getTotal();
- redisClient.zrevrange(
+ const list = await redisClient.zrevrange(
REDIS_RICH_LIST,
offset,
offset + PER_PAGE - 1,
diff --git a/server/client/redis.js b/server/client/redis.js
index 27a99405..5a5f3a49 100644
--- a/server/client/redis.js
+++ b/server/client/redis.js
@@ -1,20 +1,52 @@
-const redis = require("redis");
-const { Sentry } = require("../sentry");
+const { createClient } = require("redis");
+const {
+ DEV_REDIS_PORT,
+ PROD_REDIS_PORT,
+ REDIS_HOST,
+ REDIS_USERNAME,
+ REDIS_PASSWORD,
+ NL_REDIS_DB_INDEX,
+ NBQ_REDIS_DB_INDEX,
+ NODE_ENV,
+} = process.env;
-const { NL_REDIS_PORT, NL_REDIS_HOST, NL_REDIS_PASSWORD, NL_REDIS_DB_INDEX } = process.env;
-const client = redis.createClient(NL_REDIS_PORT, NL_REDIS_HOST, {
- password: NL_REDIS_PASSWORD,
-});
+let redisClient = null;
+async function connectRedisInstance() {
+ const REDIS_OPTIONS = {
+ ...(NODE_ENV === "development" ? { port: DEV_REDIS_PORT } : { port: PROD_REDIS_PORT }),
+ host: REDIS_HOST,
+ username: REDIS_USERNAME,
+ database: Number(NBQ_REDIS_DB_INDEX),
+ ...(NODE_ENV !== "development" && REDIS_PASSWORD ? { password: REDIS_PASSWORD } : {}),
+ };
-client.on("connect", function () {
- client.select(NL_REDIS_DB_INDEX);
- console.log(`Connected to NL Redis ON DB ${NL_REDIS_DB_INDEX}`);
-});
+ console.log("~~~~REDIS_OPTIONS", REDIS_OPTIONS);
-client.on("error", function (err) {
- Sentry.captureException(err);
-});
+ // Create a Redis client with the specified configuration options
+ redisClient = createClient(REDIS_OPTIONS);
+
+ // Properly handle connection errors
+ redisClient.on("error", err => console.log("Redis Client Error", err));
+
+ redisClient.on("connect", () => {
+ console.log("Connected to Redis server successfully!!");
+ });
+
+ // Connect to the Redis server
+ await redisClient.connect();
+
+ return redisClient;
+}
+
+// Example usage
+connectRedisInstance()
+ .then(() => {
+ console.log("Connected to NBQ Redis server successful!");
+ })
+ .catch(err => {
+ console.error("Failed to connect to Redis:", err);
+ });
module.exports = {
- client,
+ redisClient,
};
diff --git a/server/constants.js b/server/constants.js
index 46e36a89..ba0abb36 100644
--- a/server/constants.js
+++ b/server/constants.js
@@ -56,7 +56,7 @@ const PARTICIPANTS = "PARTICIPANTS";
const NANOTICKER_STATS = "NANOTICKER_STATS";
const NANOTPS_STATS = "NANOTPS_STATS";
const NANOSPEED_STATS = "NANOSPEED_STATS";
-const NANOBROWSERQUEST_PLAYERS = "NANOBROWSERQUEST_PLAYERS";
+const NANOBROWSERQUEST_ONLINE_PLAYERS = "NANOBROWSERQUEST_ONLINE_PLAYERS";
const NANOBROWSERQUEST_LEADERBOARD = "NANOBROWSERQUEST_LEADERBOARD";
const YOUTUBE_PLAYLIST = "YOUTUBE_PLAYLIST";
const MONGO_USER = process.env.MONGO_USER;
@@ -128,7 +128,7 @@ module.exports = {
NANOTICKER_STATS,
NANOTPS_STATS,
NANOSPEED_STATS,
- NANOBROWSERQUEST_PLAYERS,
+ NANOBROWSERQUEST_ONLINE_PLAYERS,
NANOBROWSERQUEST_LEADERBOARD,
YOUTUBE_PLAYLIST,
MONGO_URL,
diff --git a/server/cron/nanobrowserquestStats.js b/server/cron/nanobrowserquestStats.js
index 95256e50..1f962a37 100644
--- a/server/cron/nanobrowserquestStats.js
+++ b/server/cron/nanobrowserquestStats.js
@@ -1,98 +1,90 @@
const cron = require("node-cron");
-const redis = require("redis");
const chunk = require("lodash/chunk");
-const { Sentry } = require("../sentry");
const { nodeCache } = require("../client/cache");
-const { NANOBROWSERQUEST_PLAYERS, NANOBROWSERQUEST_LEADERBOARD } = require("../constants");
+const { redisClient } = require("../client/redis");
-const { NBQ_REDIS_PORT, NBQ_REDIS_HOST, NBQ_REDIS_PASSWORD, NBQ_REDIS_DB_INDEX } = process.env;
+const {
+ NANOBROWSERQUEST_ONLINE_PLAYERS,
+ NANOBROWSERQUEST_LEADERBOARD,
+ EXPIRE_1H,
+} = require("../constants");
-const client = redis.createClient(NBQ_REDIS_PORT, NBQ_REDIS_HOST, {
- password: NBQ_REDIS_PASSWORD,
-});
-
-client.on("connect", function () {
- client.select(NBQ_REDIS_DB_INDEX); // NBQ DB
- console.log(`Connected to NBQ Redis ON DB ${NBQ_REDIS_DB_INDEX}`);
-
- if (process.env.NODE_ENV === "production") {
- getNanoBrowserQuestLeaderboard();
- }
-});
-
-client.on("error", function (err) {
- Sentry.captureException(err);
-});
+const { NBQ_REDIS_DB_INDEX } = process.env;
const getNanoBrowserQuestPlayers = async () => {
- let res;
-
- try {
- client.get("total_players", (error, playerCount) => {
- nodeCache.set(NANOBROWSERQUEST_PLAYERS, { playerCount });
- });
- } catch (err) {
- console.log("Error", err);
- Sentry.captureException(err, { extra: { res } });
- }
+ const playerCount = await redisClient.get("total_players");
+ nodeCache.set(NANOBROWSERQUEST_ONLINE_PLAYERS, { playerCount });
};
const getNanoBrowserQuestLeaderboard = async () => {
- let res;
- try {
- let playersData = [];
- const PER_PAGES = 500;
- client.keys("u:*", async (_err, players) => {
- const playersChunks = chunk(players, PER_PAGES);
-
- for (let i = 0; i < playersChunks.length; i++) {
- const rawPlayerData = await Promise.all(
- playersChunks[i].map(
- player =>
- new Promise(resolve => {
- if (player === "u:running-coder") {
- resolve(undefined);
- }
-
- client.hmget(
- player,
- "hash",
- "network",
- "exp",
- "gold",
- "goldStash",
- (_err, reply) => {
- const network = reply[1];
- const exp = Number(reply[2] || 0);
- const gold = Number(reply[3] || 0);
- const goldStash = Number(reply[4] || 0);
-
- if (network === "ban" || !exp) {
- resolve(undefined);
- } else {
- resolve({
- player: player.replace("u:", ""),
- isCompleted: !!reply[0],
- network,
- exp: parseInt(reply[2] || 0),
- gold: gold + goldStash,
- });
- }
- },
- );
- }),
- ),
- );
-
- playersData = playersData.concat(rawPlayerData.filter(Boolean));
- }
-
- nodeCache.set(NANOBROWSERQUEST_LEADERBOARD, playersData);
- });
- } catch (err) {
- console.log("Error", err);
- Sentry.captureException(err, { extra: { res } });
+ await redisClient.select(NBQ_REDIS_DB_INDEX);
+ async function findKeys(pattern) {
+ let cursor = "0";
+ let keys = [];
+ let reply;
+
+ redisClient.select(NBQ_REDIS_DB_INDEX);
+ do {
+ reply = await redisClient.scan(
+ reply ? reply.cursor : cursor,
+ "MATCH",
+ pattern,
+ "COUNT",
+ "100",
+ );
+ // rawCursor = reply.cursor;
+
+ console.log('~~~reply.cursor',reply.cursor)
+ keys.push(...reply.keys);
+ } while (reply.cursor);
+ return keys;
+ }
+
+ let playersData = [];
+ const PER_PAGES = 2;
+ // Usage
+ const players = (await findKeys("u:*")).filter(key => key.startsWith("u:"));
+ const playersChunks = chunk(players, PER_PAGES);
+
+ console.log("~~~~~~~playersChunks", playersChunks);
+
+ for (let i = 0; i < playersChunks.length; i++) {
+ const rawPlayerData = await Promise.all(
+ playersChunks[i].map(
+ player =>
+ new Promise(async resolve => {
+ const userKey = player;
+ let [hash, network, exp, gold, goldStash] = await redisClient
+ .multi()
+ .hGet(userKey, "hash")
+ .hGet(userKey, "network")
+ .hGet(userKey, "exp")
+ .hGet(userKey, "gold")
+ .hGet(userKey, "goldStash")
+ .exec();
+
+ exp = Number(exp || 0);
+ gold = Number(gold || 0);
+ goldStash = Number(goldStash || 0);
+
+ if (network === "ban" || exp <= 1000) {
+ resolve(undefined);
+ } else {
+ resolve({
+ player: player.replace("u:", ""),
+ isCompleted: !!hash,
+ network,
+ exp,
+ gold: gold + goldStash,
+ });
+ }
+ }),
+ ),
+ );
+
+ playersData = playersData.concat(rawPlayerData.filter(Boolean));
}
+ nodeCache.set(NANOBROWSERQUEST_LEADERBOARD, playersData, EXPIRE_1H);
};
// Every 5 seconds
@@ -106,6 +98,7 @@ cron.schedule("*/15 * * * *", async () => {
getNanoBrowserQuestLeaderboard();
});
-if (!nodeCache.get(NANOBROWSERQUEST_LEADERBOARD)){
- getNanoBrowserQuestLeaderboard();
+if (!nodeCache.get(NANOBROWSERQUEST_LEADERBOARD)) {
+
+getNanoBrowserQuestLeaderboard();
}
diff --git a/server/cron/ws.js b/server/cron/ws.js
index bf23e925..bcb029b5 100644
--- a/server/cron/ws.js
+++ b/server/cron/ws.js
@@ -49,7 +49,7 @@ cron.schedule("*/3 * * * * *", async () => {
nodeCache.set(
CONFIRMATIONS_PER_SECOND,
- new BigNumber(confirmationsPerSecond).dividedBy(EXPIRE_1M).toFormat(2),
+ new BigNumber(confirmationsPerSecond || 0).dividedBy(EXPIRE_1M).toFormat(2),
);
} catch (err) {
Sentry.captureException(err, {
diff --git a/server/rpc/index.js b/server/rpc/index.js
index 9913f309..3fa0c9c0 100644
--- a/server/rpc/index.js
+++ b/server/rpc/index.js
@@ -4,6 +4,8 @@ const { transformer: representatives } = require("./transformers/representatives
const { nodeCache } = require("../client/cache");
const { Sentry } = require("../sentry");
+const { EXPIRE_1H, EXPIRE_6H, EXPIRE_48H } = require("../constants");
+
const transformers = {
confirmation_quorum,
representatives,
@@ -30,27 +32,27 @@ const allowedRpcMethods = [
"uptime",
"version",
];
-//@Note more cache due to 26.1
+
const cacheSettings = {
- account_history: 1000,
- account_info: 1000,
- account_representative: 3600,
- accounts_balances: 100,
- active_difficulty: 100,
- available_supply: 3600 * 10,
- block_count: 100,
- block_info: 100,
- blocks_info: 500,
- confirmation_history: 500,
- confirmation_quorum: 500,
- frontier_count: 500,
- peers: 3600,
- pending: 500,
- representatives: 3600 * 4,
- representatives_online: 3600 * 4,
- stats: 500,
+ account_history: 1,
+ account_info: 1,
+ account_representative: 5,
+ accounts_balances: 1,
+ active_difficulty: EXPIRE_48H,
+ available_supply: EXPIRE_6H,
+ block_count: 1,
+ block_info: 1,
+ blocks_info: 5,
+ confirmation_history: 5,
+ confirmation_quorum: 5,
+ frontier_count: 5,
+ peers: 5,
+ pending: 5,
+ representatives: EXPIRE_1H,
+ representatives_online: EXPIRE_1H,
+ stats: 5,
uptime: 30,
- version: 30,
+ version: EXPIRE_6H,
};
const limits = {
diff --git a/server/server.js b/server/server.js
index bdff2a55..dedb370c 100644
--- a/server/server.js
+++ b/server/server.js
@@ -24,7 +24,6 @@ const { getDistributionData } = require("./cron/distribution");
const { getExchangeBalances } = require("./cron/exchangeTracker");
const express = require("express");
const cors = require("cors");
-const fetch = require("node-fetch");
const { rpc, allowedRpcMethods } = require("./rpc");
const bodyParser = require("body-parser");
const path = require("path");
@@ -40,7 +39,7 @@ const {
TOTAL_VOLUME_14D,
CONFIRMATIONS_PER_SECOND,
NANOTICKER_STATS,
- NANOBROWSERQUEST_PLAYERS,
+ NANOBROWSERQUEST_ONLINE_PLAYERS,
NANOBROWSERQUEST_LEADERBOARD,
NANOTPS_STATS,
NANOSPEED_STATS,
@@ -59,17 +58,17 @@ const { getDeveloperFundTransactions } = require("./api/developerFundTransaction
const { getLargeTransactions } = require("./api/largeTransactions");
const { getNodeStatus } = require("./api/nodeStatus");
const { getKnownAccounts, getKnownAccountsBalance } = require("./api/knownAccounts");
-const { getDelegatorsPage, getAllDelegatorsCount } = require("./api/delegators");
+// const { getDelegatorsPage, getAllDelegatorsCount } = require("./api/delegators");
const { getHistoryFilters } = require("./api/historyFilters");
-const { getRichListPage, getRichListAccount } = require("./api/richList");
+// const { getRichListPage, getRichListAccount } = require("./api/richList");
const { getParticipant, getParticipantsPage } = require("./api/participants");
const { getNodeLocations } = require("./api/nodeLocations");
const { getNodeMonitors } = require("./api/nodeMonitors");
const { getDelegatedEntity } = require("./api/delegatedEntity");
const { getTelemetry } = require("./api/telemetry");
const { getRepresentative, getAllRepresentatives } = require("./api/representative");
-const { Sentry } = require("./sentry");
+
const { isValidAccountAddress } = require("./utils");
const { terminate } = require("./terminate");
@@ -110,18 +109,17 @@ app.get("/api/distribution", (req, res) => {
});
// @TODO ADD getDelegators && getAllDelegators if req.account is specified
-app.get("/api/delegators", async (req, res) => {
- let data;
- const { account, page } = req.query;
-
- if (isValidAccountAddress(account)) {
- data = await getDelegatorsPage({ account, page });
- } else {
- data = await getAllDelegatorsCount();
- }
-
- res.send(data);
-});
+// app.get("/api/delegators", async (req, res) => {
+// let data = [];
+// const { account, page } = req.query;
+// // if (isValidAccountAddress(account)) {
+// // data = await getDelegatorsPage({ account, page });
+// // } else {
+// // data = await getAllDelegatorsCount();
+// // }
+
+// res.send(data);
+// });
app.get("/api/transaction-filters", async (req, res) => {
const { account, filters } = req.query;
@@ -257,13 +255,13 @@ app.get("/api/telemetry", async (req, res) => {
});
app.get("/api/rich-list", async (req, res) => {
- const { page, account } = req.query;
- let data;
- if (page) {
- data = await getRichListPage(page);
- } else if (account) {
- data = await getRichListAccount(account);
- }
+ // const { page, account } = req.query;
+ let data = [];
+ // if (page) {
+ // data = await getRichListPage(page);
+ // } else if (account) {
+ // data = await getRichListAccount(account);
+ // }
res.send(data);
});
@@ -310,22 +308,27 @@ app.get("/api/participants", async (req, res) => {
app.get("/api/nanobrowserquest/players", async (req, res, next) => {
try {
- res.send(nodeCache.get(NANOBROWSERQUEST_PLAYERS) || {});
+ res.send(nodeCache.get(NANOBROWSERQUEST_ONLINE_PLAYERS) || {});
} catch (err) {
next(err);
}
});
app.get("/api/nanobrowserquest/leaderboard", async (req, res, next) => {
+
try {
- res.send(nodeCache.get(NANOBROWSERQUEST_LEADERBOARD) || []);
+ res.send(nodeCache.get(NANOBROWSERQUEST_LEADERBOARD));
} catch (err) {
next(err);
}
});
-app.get("/api/nanoticker", async (req, res) => {
- res.send(nodeCache.get(NANOTICKER_STATS) || {});
+app.get("/api/nanoticker", async (req, res, next) => {
+ try {
+ res.send(nodeCache.get(NANOTICKER_STATS) || {});
+ } catch (err) {
+ next(err);
+ }
});
app.get("/api/youtube-playlist", async (req, res) => {
@@ -354,3 +357,4 @@ process.on("SIGTERM", exitHandler(0, "SIGTERM"));
process.on("SIGINT", exitHandler(0, "SIGINT"));
console.log(`Server started on http://localhost:${process.env.SERVER_PORT}`);
+
diff --git a/server/ws/index.js b/server/ws/index.js
index 690c7686..98f5ee15 100644
--- a/server/ws/index.js
+++ b/server/ws/index.js
@@ -1,6 +1,6 @@
const WS = require("ws");
const BigNumber = require("bignumber.js");
-const ReconnectingWebSocket = require("reconnecting-websocket");
+const { WsReconnect } = require("websocket-reconnect");
const { Sentry } = require("../sentry");
const db = require("../client/mongo");
const {
@@ -18,15 +18,9 @@ let accumulatedVolume = 0;
let accumulatedLargeTransactionHashes = [];
// https://github.com/cryptocode/nano-websocket-sample-nodejs/blob/master/index.js
-const ws = new ReconnectingWebSocket("wss://www.nanolooker.com/ws", [], {
- WebSocket: WS,
- connectionTimeout: 10000,
- maxRetries: 100000,
- maxReconnectionDelay: 2000,
- minReconnectionDelay: 10,
-});
-
-ws.onopen = () => {
+const ws = new WsReconnect({ reconnectDelay: 5000 });
+ws.open(`wss://www.nanolooker.com/ws:${process.env.WS_PORT}`);
+ws.on("open", () => {
console.log("WS OPENED");
const subscription = {
action: "subscribe",
@@ -38,22 +32,33 @@ ws.onopen = () => {
ws.send(JSON.stringify(subscription));
updateDbInterval = setInterval(updateDb, UPDATE_CACHE_INTERVAL);
-};
+});
-ws.onclose = () => {
+ws.on("close", () => {
console.log("WS close");
clearInterval(updateDbInterval);
updateDb();
-};
+});
-ws.onerror = err => {
+ws.on("error", err => {
console.log("WS ERROR", err);
clearInterval(updateDbInterval);
updateDb();
-};
+});
ws.onmessage = msg => {
+ if (Buffer.isBuffer(msg)) {
+ const buffer = Buffer.from(msg, "hex");
+ const jsonString = buffer.toString("utf-8");
+
+ msg = {
+ data: jsonString,
+ };
+
+ }
+
const { topic, message } = JSON.parse(msg.data);
+
const {
amount,
block: { subtype },
@@ -61,7 +66,6 @@ ws.onmessage = msg => {
if (topic === "confirmation") {
accumulatedConfirmations = accumulatedConfirmations + 1;
-
// 10,000 NANO
if (subtype === "send" && amount.length >= 35) {
diff --git a/src/api/hooks/use-nanoticker.tsx b/src/api/hooks/use-nanoticker.tsx
index 78939a8f..bae77717 100644
--- a/src/api/hooks/use-nanoticker.tsx
+++ b/src/api/hooks/use-nanoticker.tsx
@@ -11,14 +11,14 @@ const useNanoTicker = (): UseUptimeReturn => {
const getConfirmationsPerSecond = async () => {
clearTimeout(confirmationsPerSecondTimeout);
- try {
+ // try {
const res = await fetch("/api/nanoticker");
const { cps } = await res.json();
setConfirmationsPerSecond(cps);
- } catch (err) {
- setConfirmationsPerSecond(undefined);
- }
+ // } catch (err) {
+ // setConfirmationsPerSecond(undefined);
+ // }
confirmationsPerSecondTimeout = window.setTimeout(() => {
getConfirmationsPerSecond();
diff --git a/src/pages/DeveloperFund/index.tsx b/src/pages/DeveloperFund/index.tsx
index 483d3f7a..e3a2da61 100644
--- a/src/pages/DeveloperFund/index.tsx
+++ b/src/pages/DeveloperFund/index.tsx
@@ -72,13 +72,12 @@ const DeveloperFund: React.FC = () => {
["desc"],
);
- const btcCurrentPrice = priceStats?.bitcoin?.[fiat] || 0;
- const fiatBalance = new BigNumber(totalBalance)
- .times(currentPrice)
- .toFormat(CurrencyDecimal?.[fiat]);
+ const btcCurrentPrice = priceStats?.bitcoin?.[fiat];
+ const fiatBalance =
+ new BigNumber(totalBalance).times(currentPrice).toFormat(CurrencyDecimal?.[fiat]) || 0;
const btcBalance = btcCurrentPrice
? new BigNumber(totalBalance).times(currentPrice).dividedBy(btcCurrentPrice).toFormat(12)
- : null;
+ : 0;
const skeletonProps = {
active: true,
@@ -135,7 +134,7 @@ const DeveloperFund: React.FC = () => {
{`${CurrencySymbol?.[fiat]} ${fiatBalance}${
diff --git a/src/pages/NanoBrowserQuest/Guide/index.tsx b/src/pages/NanoBrowserQuest/Guide/index.tsx
index ab0140f2..80c26db8 100644
--- a/src/pages/NanoBrowserQuest/Guide/index.tsx
+++ b/src/pages/NanoBrowserQuest/Guide/index.tsx
@@ -28,7 +28,7 @@ const NanoBrowserQuestGuidePage: React.FC = () => {
text = text.replace(/:rune([a-z]+):/gi, (match, capturedLetters: string) => {
//@ts-ignore
const rune = runeKind[capturedLetters];
- console.log("~~~~rune", rune);
+
const replacement = `![{"name": "${capturedLetters.toUpperCase()} Rune #${
rune.rank
}", "itemClass": "${getItemClassFromBaseLevel(rune.requirement)}", "requirement": "${
@@ -89,10 +89,7 @@ const Image: React.FC = ({ src, alt: rawAttributes }) => {
if (rawAttributes?.startsWith("{")) {
try {
title = getItemAttributes(JSON.parse(rawAttributes));
- // console.log("`~~~rawAttributes", rawAttributes);
} catch (err) {
- // console.log("`~~~rawAttributes", JSON.parse(rawAttributes));
- console.log("`~~~ERR", err);
}
return (
diff --git a/users.acl b/users.acl
new file mode 100644
index 00000000..30b48371
--- /dev/null
+++ b/users.acl
@@ -0,0 +1,4 @@
+
+#user default on>password ~* &* +@all
+user default on nopass ~* &* +@all
+user default +@all ~jobs:* on >nopass