jaelis-node 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +13 -0
  2. package/lib/index.js +106 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -187,6 +187,19 @@ Your node automatically syncs with the JAELIS network using **WebSocket push not
187
187
  - **Smart batching** - 25 blocks during initial sync, reduces as you get closer
188
188
  - **WebSocket subscriptions** - Real-time block notifications (no polling!)
189
189
  - **Automatic fallback** - Falls back to HTTP polling if WebSocket unavailable
190
+ - **Auto-update checker** - Notifies when a new version is available on npm
191
+
192
+ **Update Notifications:**
193
+ ```
194
+ ╔════════════════════════════════════════════════════════════════╗
195
+ ║ 📦 UPDATE AVAILABLE ║
196
+ ╠════════════════════════════════════════════════════════════════╣
197
+ ║ Current: v1.9.0 → Latest: v1.10.0 ║
198
+ ║ ║
199
+ ║ Run: npm update -g jaelis-node ║
200
+ ║ Or: npx jaelis-node@latest start ║
201
+ ╚════════════════════════════════════════════════════════════════╝
202
+ ```
190
203
 
191
204
  ```bash
192
205
  # Check sync status
package/lib/index.js CHANGED
@@ -22,7 +22,7 @@
22
22
  * This follows Solana/Cosmos/Polkadot patterns for multi-ecosystem support.
23
23
  * ═══════════════════════════════════════════════════════════════════════════════
24
24
  *
25
- * @version 1.4.0
25
+ * @version 1.9.0
26
26
  * @author JAELIS Foundation
27
27
  */
28
28
 
@@ -516,6 +516,9 @@ class JaelisNode extends EventEmitter {
516
516
 
517
517
  console.log(`[JAELIS] Node started successfully`);
518
518
 
519
+ // Check for updates (non-blocking)
520
+ this._checkForUpdates();
521
+
519
522
  } catch (error) {
520
523
  console.error(`[JAELIS] Failed to start node: ${error.message}`);
521
524
  throw error;
@@ -739,12 +742,13 @@ class JaelisNode extends EventEmitter {
739
742
  const identity = this.walletConfig.getNodeIdentity();
740
743
  const rewardRecipient = this.walletConfig.getRewardRecipient();
741
744
 
745
+ const packageJson = require('../package.json');
742
746
  const nodeInfo = {
743
747
  nodeId: identity.id,
744
748
  publicKey: identity.publicKey,
745
749
  network: this.options.network,
746
750
  chainId: this.options.chainId,
747
- version: '1.3.0',
751
+ version: packageJson.version,
748
752
  rewardAddress: rewardRecipient?.address || null,
749
753
  rewardChainType: rewardRecipient?.type || null,
750
754
  capabilities: ['full-node', 'rpc'],
@@ -773,7 +777,7 @@ class JaelisNode extends EventEmitter {
773
777
  headers: {
774
778
  'Content-Type': 'application/json',
775
779
  'Content-Length': Buffer.byteLength(data),
776
- 'User-Agent': 'JAELIS-Node/1.7.0' // Identifies us as a node - gets priority treatment
780
+ 'User-Agent': `JAELIS-Node/${packageJson.version}` // Identifies us as a node - gets priority treatment
777
781
  }
778
782
  };
779
783
 
@@ -811,6 +815,7 @@ class JaelisNode extends EventEmitter {
811
815
  */
812
816
  _startHeartbeat() {
813
817
  const HEARTBEAT_INTERVAL = 60000; // 60 seconds
818
+ const packageJson = require('../package.json');
814
819
 
815
820
  this._heartbeatInterval = setInterval(async () => {
816
821
  if (!this.isRunning || !this._nodeInfo) return;
@@ -837,7 +842,7 @@ class JaelisNode extends EventEmitter {
837
842
  headers: {
838
843
  'Content-Type': 'application/json',
839
844
  'Content-Length': Buffer.byteLength(data),
840
- 'User-Agent': 'JAELIS-Node/1.7.0' // Identifies us as a node - gets priority treatment
845
+ 'User-Agent': `JAELIS-Node/${packageJson.version}` // Identifies us as a node - gets priority treatment
841
846
  }
842
847
  };
843
848
 
@@ -854,6 +859,79 @@ class JaelisNode extends EventEmitter {
854
859
  console.log('[JAELIS] Heartbeat started (60s interval)');
855
860
  }
856
861
 
862
+ /**
863
+ * Check for updates from npm registry
864
+ * Non-blocking - just notifies if a new version is available
865
+ */
866
+ async _checkForUpdates() {
867
+ try {
868
+ const https = require('https');
869
+ const packageJson = require('../package.json');
870
+ const currentVersion = packageJson.version;
871
+
872
+ const options = {
873
+ hostname: 'registry.npmjs.org',
874
+ path: '/jaelis-node/latest',
875
+ method: 'GET',
876
+ headers: {
877
+ 'Accept': 'application/json',
878
+ 'User-Agent': `JAELIS-Node/${currentVersion}`
879
+ },
880
+ timeout: 5000
881
+ };
882
+
883
+ const req = https.request(options, (res) => {
884
+ let body = '';
885
+ res.on('data', chunk => body += chunk);
886
+ res.on('end', () => {
887
+ try {
888
+ const data = JSON.parse(body);
889
+ const latestVersion = data.version;
890
+
891
+ if (latestVersion && this._isNewerVersion(currentVersion, latestVersion)) {
892
+ console.log('');
893
+ console.log('╔════════════════════════════════════════════════════════════════╗');
894
+ console.log('║ 📦 UPDATE AVAILABLE ║');
895
+ console.log('╠════════════════════════════════════════════════════════════════╣');
896
+ console.log(`║ Current: v${currentVersion.padEnd(10)} → Latest: v${latestVersion.padEnd(20)}║`);
897
+ console.log('║ ║');
898
+ console.log('║ Run: npm update -g jaelis-node ║');
899
+ console.log('║ Or: npx jaelis-node@latest start ║');
900
+ console.log('╚════════════════════════════════════════════════════════════════╝');
901
+ console.log('');
902
+ }
903
+ } catch (e) {
904
+ // Silent - update check is best-effort
905
+ }
906
+ });
907
+ });
908
+
909
+ req.on('error', () => {}); // Silent fail
910
+ req.on('timeout', () => req.destroy());
911
+ req.end();
912
+
913
+ } catch (error) {
914
+ // Update check is non-critical, fail silently
915
+ }
916
+ }
917
+
918
+ /**
919
+ * Compare semver versions
920
+ * @returns true if latest > current
921
+ */
922
+ _isNewerVersion(current, latest) {
923
+ const currentParts = current.split('.').map(Number);
924
+ const latestParts = latest.split('.').map(Number);
925
+
926
+ for (let i = 0; i < 3; i++) {
927
+ const c = currentParts[i] || 0;
928
+ const l = latestParts[i] || 0;
929
+ if (l > c) return true;
930
+ if (l < c) return false;
931
+ }
932
+ return false;
933
+ }
934
+
857
935
  /**
858
936
  * Stop heartbeat
859
937
  */
@@ -868,18 +946,40 @@ class JaelisNode extends EventEmitter {
868
946
  * Get node status
869
947
  */
870
948
  getStatus() {
949
+ const packageJson = require('../package.json');
950
+ const uptimeMs = this.startTime ? Date.now() - this.startTime : 0;
951
+
871
952
  return {
953
+ healthy: this.isRunning,
872
954
  running: this.isRunning,
955
+ version: packageJson.version,
873
956
  network: this.options.network,
874
957
  chainId: this.options.chainId,
875
- uptime: this.startTime ? Date.now() - this.startTime : 0,
958
+ uptime: uptimeMs,
959
+ uptimeHuman: this._formatUptime(uptimeMs),
876
960
  peers: this.peerCount,
877
961
  rpcPort: this.options.rpcPort,
878
962
  p2pPort: this.options.p2pPort,
879
963
  syncMode: this.options.syncMode,
880
- blockHeight: this.blockchain?.getHeight?.() || 0
964
+ blockHeight: this.blockchain?.getHeight?.() || 0,
965
+ nodeId: this._nodeInfo?.nodeId?.slice(0, 16) + '...' || null
881
966
  };
882
967
  }
968
+
969
+ /**
970
+ * Format uptime in human readable format
971
+ */
972
+ _formatUptime(ms) {
973
+ const seconds = Math.floor(ms / 1000);
974
+ const minutes = Math.floor(seconds / 60);
975
+ const hours = Math.floor(minutes / 60);
976
+ const days = Math.floor(hours / 24);
977
+
978
+ if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`;
979
+ if (hours > 0) return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
980
+ if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
981
+ return `${seconds}s`;
982
+ }
883
983
  }
884
984
 
885
985
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jaelis-node",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Official JAELIS Blockchain Node - WebSocket real-time sync, Universal VM (6 languages), LevelDB state persistence, native jaelis_* RPC, multi-ecosystem compatibility (eth/solana/move/ton/btc/wasm/starknet), Cross-Chain Settlement (30+ chains!), AI-native MCP integration",
5
5
  "main": "lib/index.js",
6
6
  "bin": {