jaelis-node 1.10.0 → 2.0.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.
- package/README.md +146 -445
- package/bin/jaelis-node.js +79 -504
- package/lib/index.js +31 -2840
- package/lib/node.js +271 -0
- package/lib/rpc.js +315 -0
- package/lib/storage.js +198 -0
- package/lib/sync.js +366 -0
- package/package.json +19 -53
- package/config/default.json +0 -74
- package/config/mainnet.json +0 -30
- package/config/testnet.json +0 -26
- package/lib/JAELIS-VM/lib/adapters/evm-adapter.js +0 -454
- package/lib/JAELIS-VM/lib/adapters/index.js +0 -411
- package/lib/JAELIS-VM/lib/adapters/svm-adapter.js +0 -457
- package/lib/JAELIS-VM/lib/compiler/jir-compiler.js +0 -1097
- package/lib/JAELIS-VM/lib/execution/engine.js +0 -1183
- package/lib/JAELIS-VM/lib/index.js +0 -440
- package/lib/JAELIS-VM/lib/integration/jaelis-integration.js +0 -543
- package/lib/JAELIS-VM/lib/serialization/serializer.js +0 -819
- package/lib/JAELIS-VM/lib/state/state-manager.js +0 -1116
- package/lib/JAELIS-VM/lib/translator/bytecode-translator.js +0 -1222
- package/lib/JAELIS-VM/lib/unified/cross-chain-deploy.js +0 -1678
- package/lib/JAELIS-VM/lib/unified/cross-chain-state.js +0 -836
- package/lib/JAELIS-VM/lib/unified/dynamic-contracts.js +0 -1127
- package/lib/JAELIS-VM/lib/unified/index.js +0 -456
- package/lib/JAELIS-VM/lib/unified/jaelis-abi.js +0 -1150
- package/lib/JAELIS-VM/lib/unified/unified-compiler.js +0 -1350
- package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.package-lock.json +0 -127
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/README.md +0 -1
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/index.js +0 -0
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.abi115.node +0 -0
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.napi.node +0 -0
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/package.json +0 -17
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/README.md +0 -1
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/index.js +0 -0
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.abi115.node +0 -0
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.napi.node +0 -0
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/package.json +0 -17
- package/lib/JAELIS-VM/node_modules/cbor-extract/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/cbor-extract/README.md +0 -5
- package/lib/JAELIS-VM/node_modules/cbor-extract/bin/download-prebuilds.js +0 -11
- package/lib/JAELIS-VM/node_modules/cbor-extract/binding.gyp +0 -60
- package/lib/JAELIS-VM/node_modules/cbor-extract/index.js +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-extract/package.json +0 -50
- package/lib/JAELIS-VM/node_modules/cbor-extract/src/extract.cpp +0 -198
- package/lib/JAELIS-VM/node_modules/cbor-x/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/cbor-x/README.md +0 -380
- package/lib/JAELIS-VM/node_modules/cbor-x/SECURITY.md +0 -11
- package/lib/JAELIS-VM/node_modules/cbor-x/benchmark.md +0 -73
- package/lib/JAELIS-VM/node_modules/cbor-x/browser.js +0 -11
- package/lib/JAELIS-VM/node_modules/cbor-x/decode.d.ts +0 -2
- package/lib/JAELIS-VM/node_modules/cbor-x/decode.js +0 -1300
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs +0 -1244
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs +0 -2509
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js +0 -2508
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs +0 -2629
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js +0 -3343
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/encode.d.ts +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/encode.js +0 -1231
- package/lib/JAELIS-VM/node_modules/cbor-x/index.d.ts +0 -79
- package/lib/JAELIS-VM/node_modules/cbor-x/index.js +0 -3
- package/lib/JAELIS-VM/node_modules/cbor-x/iterators.js +0 -85
- package/lib/JAELIS-VM/node_modules/cbor-x/node-index.js +0 -24
- package/lib/JAELIS-VM/node_modules/cbor-x/package.json +0 -94
- package/lib/JAELIS-VM/node_modules/cbor-x/rollup.config.js +0 -88
- package/lib/JAELIS-VM/node_modules/cbor-x/stream.js +0 -61
- package/lib/JAELIS-VM/node_modules/cbor-x/webpack.config.js +0 -19
- package/lib/JAELIS-VM/node_modules/detect-libc/LICENSE +0 -201
- package/lib/JAELIS-VM/node_modules/detect-libc/README.md +0 -163
- package/lib/JAELIS-VM/node_modules/detect-libc/index.d.ts +0 -14
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/detect-libc.js +0 -313
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/elf.js +0 -39
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/filesystem.js +0 -51
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/process.js +0 -24
- package/lib/JAELIS-VM/node_modules/detect-libc/package.json +0 -44
- package/lib/JAELIS-VM/node_modules/msgpackr/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/msgpackr/README.md +0 -372
- package/lib/JAELIS-VM/node_modules/msgpackr/SECURITY.md +0 -11
- package/lib/JAELIS-VM/node_modules/msgpackr/benchmark.md +0 -67
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs +0 -2407
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js +0 -2406
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs +0 -3320
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js +0 -4540
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs +0 -1250
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/index.d.cts +0 -91
- package/lib/JAELIS-VM/node_modules/msgpackr/index.d.ts +0 -91
- package/lib/JAELIS-VM/node_modules/msgpackr/index.js +0 -5
- package/lib/JAELIS-VM/node_modules/msgpackr/iterators.js +0 -87
- package/lib/JAELIS-VM/node_modules/msgpackr/node-index.js +0 -25
- package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.cts +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.ts +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/pack.js +0 -1141
- package/lib/JAELIS-VM/node_modules/msgpackr/package.json +0 -104
- package/lib/JAELIS-VM/node_modules/msgpackr/rollup.config.js +0 -88
- package/lib/JAELIS-VM/node_modules/msgpackr/stream.js +0 -57
- package/lib/JAELIS-VM/node_modules/msgpackr/struct.js +0 -815
- package/lib/JAELIS-VM/node_modules/msgpackr/test-worker.js +0 -3
- package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.cts +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.ts +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/unpack.js +0 -1221
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/README.md +0 -5
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/bin/download-prebuilds.js +0 -13
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/binding.gyp +0 -63
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/index.js +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages +0 -12
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/README.md +0 -58
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/bin.js +0 -82
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/index.js +0 -6
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +0 -236
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/package.json +0 -32
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/package.json +0 -50
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/src/extract.cpp +0 -274
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/README.md +0 -58
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/bin.js +0 -77
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/index.js +0 -224
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/package.json +0 -32
- package/lib/JAELIS-VM/package-lock.json +0 -284
- package/lib/JAELIS-VM/package.json +0 -38
- package/lib/JAELIS-VM/test/comprehensive.test.js +0 -267
- package/lib/JAELIS-VM/test/cross-chain-test.js +0 -470
- package/lib/JAELIS-VM/test/unified-vm-test.js +0 -459
- package/lib/JAELIS-VM/test/unified.test.js +0 -166
- package/lib/JAELIS-VM/test/vm.test.js +0 -599
- package/lib/settlement-server.js +0 -999
- package/lib/vm/index.js +0 -397
package/lib/node.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JAELIS External Node
|
|
3
|
+
*
|
|
4
|
+
* Lightweight node that connects to the JAELIS network.
|
|
5
|
+
* Does NOT contain any internal JAELIS blockchain code.
|
|
6
|
+
* Only implements the network protocol for syncing and RPC.
|
|
7
|
+
*
|
|
8
|
+
* @version 2.0.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const EventEmitter = require('events');
|
|
14
|
+
const { SyncManager } = require('./sync');
|
|
15
|
+
const { RPCServer } = require('./rpc');
|
|
16
|
+
const { Storage } = require('./storage');
|
|
17
|
+
|
|
18
|
+
// Network configurations
|
|
19
|
+
const NETWORKS = {
|
|
20
|
+
testnet: {
|
|
21
|
+
name: 'JAELIS Testnet',
|
|
22
|
+
chainId: 4545,
|
|
23
|
+
symbol: 'tJAELIS',
|
|
24
|
+
rpcEndpoint: 'https://rpc.jaelis.io',
|
|
25
|
+
wsEndpoint: 'wss://rpc.jaelis.io/ws'
|
|
26
|
+
},
|
|
27
|
+
mainnet: {
|
|
28
|
+
name: 'JAELIS Mainnet',
|
|
29
|
+
chainId: 4547,
|
|
30
|
+
symbol: 'JAELIS',
|
|
31
|
+
rpcEndpoint: 'https://mainnet.jaelis.io',
|
|
32
|
+
wsEndpoint: 'wss://mainnet.jaelis.io/ws'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
class JaelisNode extends EventEmitter {
|
|
37
|
+
/**
|
|
38
|
+
* Create a new JAELIS external node
|
|
39
|
+
* @param {Object} options - Node configuration
|
|
40
|
+
* @param {string} options.network - Network name ('testnet' or 'mainnet')
|
|
41
|
+
* @param {string} options.dataDir - Data directory for local storage
|
|
42
|
+
* @param {number} options.rpcPort - Local RPC port (default: 8545)
|
|
43
|
+
* @param {boolean} options.enableRpc - Enable local RPC server (default: true)
|
|
44
|
+
*/
|
|
45
|
+
constructor(options = {}) {
|
|
46
|
+
super();
|
|
47
|
+
|
|
48
|
+
// Configuration
|
|
49
|
+
this.network = options.network || 'testnet';
|
|
50
|
+
this.networkConfig = NETWORKS[this.network];
|
|
51
|
+
if (!this.networkConfig) {
|
|
52
|
+
throw new Error(`Unknown network: ${this.network}. Use 'testnet' or 'mainnet'.`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.dataDir = options.dataDir || `./jaelis-data/${this.network}`;
|
|
56
|
+
this.rpcPort = options.rpcPort || 8545;
|
|
57
|
+
this.enableRpc = options.enableRpc !== false;
|
|
58
|
+
|
|
59
|
+
// Node state
|
|
60
|
+
this.nodeId = this._generateNodeId();
|
|
61
|
+
this.startTime = null;
|
|
62
|
+
this.isRunning = false;
|
|
63
|
+
this.isSyncing = false;
|
|
64
|
+
|
|
65
|
+
// Components (initialized on start)
|
|
66
|
+
this.storage = null;
|
|
67
|
+
this.sync = null;
|
|
68
|
+
this.rpc = null;
|
|
69
|
+
|
|
70
|
+
// Stats
|
|
71
|
+
this.stats = {
|
|
72
|
+
blocksReceived: 0,
|
|
73
|
+
transactionsRelayed: 0,
|
|
74
|
+
rpcRequests: 0,
|
|
75
|
+
peersConnected: 0
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Generate unique node ID
|
|
81
|
+
*/
|
|
82
|
+
_generateNodeId() {
|
|
83
|
+
const crypto = require('crypto');
|
|
84
|
+
return 'jaelis_' + crypto.randomBytes(8).toString('hex');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Start the node
|
|
89
|
+
*/
|
|
90
|
+
async start() {
|
|
91
|
+
if (this.isRunning) {
|
|
92
|
+
throw new Error('Node is already running');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log('');
|
|
96
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
97
|
+
console.log(' JAELIS EXTERNAL NODE v2.0.0');
|
|
98
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
99
|
+
console.log(` Network: ${this.networkConfig.name}`);
|
|
100
|
+
console.log(` Chain ID: ${this.networkConfig.chainId}`);
|
|
101
|
+
console.log(` Node ID: ${this.nodeId}`);
|
|
102
|
+
console.log(` Data Dir: ${this.dataDir}`);
|
|
103
|
+
console.log('═══════════════════════════════════════════════════════════════');
|
|
104
|
+
console.log('');
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
// Initialize storage
|
|
108
|
+
console.log('[NODE] Initializing local storage...');
|
|
109
|
+
this.storage = new Storage(this.dataDir);
|
|
110
|
+
await this.storage.initialize();
|
|
111
|
+
|
|
112
|
+
// Initialize sync manager
|
|
113
|
+
console.log('[NODE] Connecting to JAELIS network...');
|
|
114
|
+
this.sync = new SyncManager({
|
|
115
|
+
wsEndpoint: this.networkConfig.wsEndpoint,
|
|
116
|
+
rpcEndpoint: this.networkConfig.rpcEndpoint,
|
|
117
|
+
storage: this.storage,
|
|
118
|
+
chainId: this.networkConfig.chainId
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Forward sync events
|
|
122
|
+
this.sync.on('connected', () => {
|
|
123
|
+
console.log('[NODE] Connected to JAELIS network');
|
|
124
|
+
this.emit('connected');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.sync.on('disconnected', () => {
|
|
128
|
+
console.log('[NODE] Disconnected from network');
|
|
129
|
+
this.emit('disconnected');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
this.sync.on('block', (block) => {
|
|
133
|
+
this.stats.blocksReceived++;
|
|
134
|
+
this.emit('block', block);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
this.sync.on('syncing', (status) => {
|
|
138
|
+
this.isSyncing = status.syncing;
|
|
139
|
+
this.emit('syncing', status);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
this.sync.on('synced', () => {
|
|
143
|
+
this.isSyncing = false;
|
|
144
|
+
console.log('[NODE] Fully synced with network');
|
|
145
|
+
this.emit('synced');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Start sync
|
|
149
|
+
await this.sync.start();
|
|
150
|
+
|
|
151
|
+
// Start RPC server if enabled
|
|
152
|
+
if (this.enableRpc) {
|
|
153
|
+
console.log(`[NODE] Starting local RPC server on port ${this.rpcPort}...`);
|
|
154
|
+
this.rpc = new RPCServer({
|
|
155
|
+
port: this.rpcPort,
|
|
156
|
+
storage: this.storage,
|
|
157
|
+
sync: this.sync,
|
|
158
|
+
chainId: this.networkConfig.chainId,
|
|
159
|
+
networkName: this.networkConfig.name
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
this.rpc.on('request', () => {
|
|
163
|
+
this.stats.rpcRequests++;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await this.rpc.start();
|
|
167
|
+
console.log(`[NODE] Local RPC available at http://localhost:${this.rpcPort}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
this.startTime = Date.now();
|
|
171
|
+
this.isRunning = true;
|
|
172
|
+
|
|
173
|
+
console.log('');
|
|
174
|
+
console.log('[NODE] Node started successfully!');
|
|
175
|
+
console.log('');
|
|
176
|
+
|
|
177
|
+
this.emit('started');
|
|
178
|
+
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error('[NODE] Failed to start:', error.message);
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Stop the node
|
|
187
|
+
*/
|
|
188
|
+
async stop() {
|
|
189
|
+
if (!this.isRunning) return;
|
|
190
|
+
|
|
191
|
+
console.log('[NODE] Stopping node...');
|
|
192
|
+
|
|
193
|
+
if (this.rpc) {
|
|
194
|
+
await this.rpc.stop();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (this.sync) {
|
|
198
|
+
await this.sync.stop();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (this.storage) {
|
|
202
|
+
await this.storage.close();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
this.isRunning = false;
|
|
206
|
+
console.log('[NODE] Node stopped');
|
|
207
|
+
this.emit('stopped');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get node status
|
|
212
|
+
*/
|
|
213
|
+
getStatus() {
|
|
214
|
+
const uptime = this.startTime ? Date.now() - this.startTime : 0;
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
nodeId: this.nodeId,
|
|
218
|
+
network: this.network,
|
|
219
|
+
chainId: this.networkConfig.chainId,
|
|
220
|
+
isRunning: this.isRunning,
|
|
221
|
+
isSyncing: this.isSyncing,
|
|
222
|
+
uptime,
|
|
223
|
+
uptimeFormatted: this._formatUptime(uptime),
|
|
224
|
+
currentBlock: this.storage?.getLatestBlockNumber() || 0,
|
|
225
|
+
stats: this.stats,
|
|
226
|
+
version: '2.0.0',
|
|
227
|
+
rpcPort: this.enableRpc ? this.rpcPort : null
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Format uptime as human-readable string
|
|
233
|
+
*/
|
|
234
|
+
_formatUptime(ms) {
|
|
235
|
+
const seconds = Math.floor(ms / 1000);
|
|
236
|
+
const minutes = Math.floor(seconds / 60);
|
|
237
|
+
const hours = Math.floor(minutes / 60);
|
|
238
|
+
const days = Math.floor(hours / 24);
|
|
239
|
+
|
|
240
|
+
if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`;
|
|
241
|
+
if (hours > 0) return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
242
|
+
if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
|
|
243
|
+
return `${seconds}s`;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get latest block number
|
|
248
|
+
*/
|
|
249
|
+
async getBlockNumber() {
|
|
250
|
+
return this.storage?.getLatestBlockNumber() || 0;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get block by number
|
|
255
|
+
*/
|
|
256
|
+
async getBlock(blockNumber) {
|
|
257
|
+
return this.storage?.getBlock(blockNumber);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Submit transaction to the network
|
|
262
|
+
*/
|
|
263
|
+
async sendTransaction(signedTx) {
|
|
264
|
+
if (!this.sync?.isConnected) {
|
|
265
|
+
throw new Error('Not connected to network');
|
|
266
|
+
}
|
|
267
|
+
return this.sync.sendTransaction(signedTx);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
module.exports = { JaelisNode, NETWORKS };
|
package/lib/rpc.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JAELIS Local RPC Server
|
|
3
|
+
*
|
|
4
|
+
* JSON-RPC server for local dApp access.
|
|
5
|
+
* Reads from local storage and relays transactions to network.
|
|
6
|
+
*
|
|
7
|
+
* JAELIS is a sovereign L1 blockchain - uses jaelis_* namespace ONLY.
|
|
8
|
+
* No eth_* aliasing. Like Solana uses native methods, so does JAELIS.
|
|
9
|
+
*
|
|
10
|
+
* @version 2.0.0
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const EventEmitter = require('events');
|
|
16
|
+
const http = require('http');
|
|
17
|
+
|
|
18
|
+
class RPCServer extends EventEmitter {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
super();
|
|
21
|
+
|
|
22
|
+
this.port = options.port || 8545;
|
|
23
|
+
this.storage = options.storage;
|
|
24
|
+
this.sync = options.sync;
|
|
25
|
+
this.chainId = options.chainId;
|
|
26
|
+
this.networkName = options.networkName;
|
|
27
|
+
|
|
28
|
+
this.server = null;
|
|
29
|
+
this.isRunning = false;
|
|
30
|
+
|
|
31
|
+
// Method handlers
|
|
32
|
+
this.methods = this._registerMethods();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Start RPC server
|
|
37
|
+
*/
|
|
38
|
+
async start() {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
this.server = http.createServer((req, res) => {
|
|
41
|
+
this._handleRequest(req, res);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
this.server.listen(this.port, () => {
|
|
45
|
+
this.isRunning = true;
|
|
46
|
+
resolve();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
this.server.on('error', reject);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Stop RPC server
|
|
55
|
+
*/
|
|
56
|
+
async stop() {
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
if (this.server) {
|
|
59
|
+
this.server.close(() => {
|
|
60
|
+
this.isRunning = false;
|
|
61
|
+
resolve();
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
64
|
+
resolve();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Handle incoming HTTP request
|
|
71
|
+
*/
|
|
72
|
+
async _handleRequest(req, res) {
|
|
73
|
+
// CORS headers
|
|
74
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
75
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
76
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
77
|
+
|
|
78
|
+
// Handle preflight
|
|
79
|
+
if (req.method === 'OPTIONS') {
|
|
80
|
+
res.writeHead(204);
|
|
81
|
+
res.end();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Only accept POST
|
|
86
|
+
if (req.method !== 'POST') {
|
|
87
|
+
res.writeHead(405);
|
|
88
|
+
res.end('Method Not Allowed');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Read body
|
|
93
|
+
let body = '';
|
|
94
|
+
req.on('data', chunk => body += chunk);
|
|
95
|
+
req.on('end', async () => {
|
|
96
|
+
try {
|
|
97
|
+
const request = JSON.parse(body);
|
|
98
|
+
this.emit('request', request);
|
|
99
|
+
|
|
100
|
+
// Handle batch or single
|
|
101
|
+
let response;
|
|
102
|
+
if (Array.isArray(request)) {
|
|
103
|
+
response = await Promise.all(request.map(r => this._handleRpcCall(r)));
|
|
104
|
+
} else {
|
|
105
|
+
response = await this._handleRpcCall(request);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
res.setHeader('Content-Type', 'application/json');
|
|
109
|
+
res.writeHead(200);
|
|
110
|
+
res.end(JSON.stringify(response));
|
|
111
|
+
|
|
112
|
+
} catch (error) {
|
|
113
|
+
res.setHeader('Content-Type', 'application/json');
|
|
114
|
+
res.writeHead(200);
|
|
115
|
+
res.end(JSON.stringify({
|
|
116
|
+
jsonrpc: '2.0',
|
|
117
|
+
id: null,
|
|
118
|
+
error: { code: -32700, message: 'Parse error' }
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Handle single RPC call
|
|
126
|
+
*/
|
|
127
|
+
async _handleRpcCall(request) {
|
|
128
|
+
const { jsonrpc, id, method, params } = request;
|
|
129
|
+
|
|
130
|
+
if (jsonrpc !== '2.0') {
|
|
131
|
+
return { jsonrpc: '2.0', id, error: { code: -32600, message: 'Invalid Request' } };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// JAELIS is sovereign - use jaelis_* methods only
|
|
135
|
+
// No eth_* aliasing - we are our own chain
|
|
136
|
+
const handler = this.methods.get(method);
|
|
137
|
+
if (!handler) {
|
|
138
|
+
return { jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' } };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const result = await handler(params || []);
|
|
143
|
+
return { jsonrpc: '2.0', id, result };
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return { jsonrpc: '2.0', id, error: { code: -32000, message: error.message } };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Register RPC methods
|
|
151
|
+
*/
|
|
152
|
+
_registerMethods() {
|
|
153
|
+
const methods = new Map();
|
|
154
|
+
|
|
155
|
+
// Chain info
|
|
156
|
+
methods.set('jaelis_chainId', async () => {
|
|
157
|
+
return '0x' + this.chainId.toString(16);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
methods.set('jaelis_networkId', async () => {
|
|
161
|
+
return this.chainId.toString();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
methods.set('jaelis_blockNumber', async () => {
|
|
165
|
+
const blockNumber = this.storage.getLatestBlockNumber();
|
|
166
|
+
return '0x' + blockNumber.toString(16);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Block queries
|
|
170
|
+
methods.set('jaelis_getBlockByNumber', async (params) => {
|
|
171
|
+
const [blockTag, includeTxs] = params;
|
|
172
|
+
let blockNumber;
|
|
173
|
+
|
|
174
|
+
if (blockTag === 'latest') {
|
|
175
|
+
blockNumber = this.storage.getLatestBlockNumber();
|
|
176
|
+
} else if (blockTag === 'earliest') {
|
|
177
|
+
blockNumber = 0;
|
|
178
|
+
} else {
|
|
179
|
+
blockNumber = parseInt(blockTag, 16);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const block = await this.storage.getBlock(blockNumber);
|
|
183
|
+
if (!block) return null;
|
|
184
|
+
|
|
185
|
+
// Strip full transactions if not requested
|
|
186
|
+
if (!includeTxs && block.transactions) {
|
|
187
|
+
return {
|
|
188
|
+
...block,
|
|
189
|
+
transactions: block.transactions.map(tx =>
|
|
190
|
+
typeof tx === 'object' ? tx.hash : tx
|
|
191
|
+
)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return block;
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
methods.set('jaelis_getBlockByHash', async () => {
|
|
199
|
+
// Hash lookup not indexed yet - return null
|
|
200
|
+
return null;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Transaction queries
|
|
204
|
+
methods.set('jaelis_getTransactionByHash', async (params) => {
|
|
205
|
+
const [txHash] = params;
|
|
206
|
+
return this.storage.getTransaction(txHash);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
methods.set('jaelis_getTransactionReceipt', async (params) => {
|
|
210
|
+
const [txHash] = params;
|
|
211
|
+
const tx = await this.storage.getTransaction(txHash);
|
|
212
|
+
if (!tx) return null;
|
|
213
|
+
|
|
214
|
+
// Return basic receipt (actual receipt would come from network)
|
|
215
|
+
return {
|
|
216
|
+
transactionHash: txHash,
|
|
217
|
+
blockNumber: tx.blockNumber,
|
|
218
|
+
blockHash: tx.blockHash,
|
|
219
|
+
status: '0x1',
|
|
220
|
+
from: tx.from,
|
|
221
|
+
to: tx.to,
|
|
222
|
+
gasUsed: '0x0', // JAELIS has no gas
|
|
223
|
+
logs: []
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Transaction submission
|
|
228
|
+
methods.set('jaelis_sendRawTransaction', async (params) => {
|
|
229
|
+
const [signedTx] = params;
|
|
230
|
+
return this.sync.sendTransaction(signedTx);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Account queries (relay to main network)
|
|
234
|
+
methods.set('jaelis_getBalance', async (params) => {
|
|
235
|
+
const [address, blockTag] = params;
|
|
236
|
+
return this.sync._httpRpc('jaelis_getBalance', [address, blockTag || 'latest']);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
methods.set('jaelis_getTransactionCount', async (params) => {
|
|
240
|
+
const [address, blockTag] = params;
|
|
241
|
+
return this.sync._httpRpc('jaelis_getTransactionCount', [address, blockTag || 'latest']);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// ENE (Ephemeral Network Entropy) - replaces nonces in JAELIS
|
|
245
|
+
// Provides post-quantum safe transaction ordering
|
|
246
|
+
methods.set('jaelis_getENE', async (params) => {
|
|
247
|
+
const [address] = params;
|
|
248
|
+
return this.sync._httpRpc('jaelis_getENE', [address]);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// SIGIL compute estimation (NOT gas - JAELIS has zero fees!)
|
|
252
|
+
methods.set('jaelis_estimateSigil', async (params) => {
|
|
253
|
+
const [txObject] = params;
|
|
254
|
+
return this.sync._httpRpc('jaelis_estimateSigil', [txObject]);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Get account SIGIL allocation
|
|
258
|
+
methods.set('jaelis_getSigil', async (params) => {
|
|
259
|
+
const [address] = params;
|
|
260
|
+
return this.sync._httpRpc('jaelis_getSigil', [address]);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
methods.set('jaelis_getCode', async (params) => {
|
|
264
|
+
const [address, blockTag] = params;
|
|
265
|
+
return this.sync._httpRpc('jaelis_getCode', [address, blockTag || 'latest']);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
methods.set('jaelis_call', async (params) => {
|
|
269
|
+
const [callObject, blockTag] = params;
|
|
270
|
+
return this.sync._httpRpc('jaelis_call', [callObject, blockTag || 'latest']);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Gas (always returns 0 for JAELIS)
|
|
274
|
+
methods.set('jaelis_gasPrice', async () => {
|
|
275
|
+
return '0x0'; // Zero gas fees!
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
methods.set('jaelis_estimateGas', async () => {
|
|
279
|
+
return '0x0'; // Zero gas fees!
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Syncing status
|
|
283
|
+
methods.set('jaelis_syncing', async () => {
|
|
284
|
+
if (!this.sync.isSyncing) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
startingBlock: '0x0',
|
|
289
|
+
currentBlock: '0x' + this.storage.getLatestBlockNumber().toString(16),
|
|
290
|
+
highestBlock: '0x' + this.sync.networkHeight.toString(16)
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Node info
|
|
295
|
+
methods.set('web3_clientVersion', async () => {
|
|
296
|
+
return `JAELIS-Node/v2.0.0/${this.networkName}`;
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
methods.set('net_version', async () => {
|
|
300
|
+
return this.chainId.toString();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
methods.set('net_listening', async () => {
|
|
304
|
+
return this.sync.isConnected;
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
methods.set('net_peerCount', async () => {
|
|
308
|
+
return '0x1'; // Connected to main network
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
return methods;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
module.exports = { RPCServer };
|