jaelis-node 1.3.1 → 1.4.1

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 (162) hide show
  1. package/README.md +72 -2
  2. package/lib/JAELIS-VM/lib/adapters/evm-adapter.js +454 -0
  3. package/lib/JAELIS-VM/lib/adapters/index.js +411 -0
  4. package/lib/JAELIS-VM/lib/adapters/svm-adapter.js +457 -0
  5. package/lib/JAELIS-VM/lib/compiler/jir-compiler.js +1097 -0
  6. package/lib/JAELIS-VM/lib/execution/engine.js +1183 -0
  7. package/lib/JAELIS-VM/lib/index.js +440 -0
  8. package/lib/JAELIS-VM/lib/integration/jaelis-integration.js +543 -0
  9. package/lib/JAELIS-VM/lib/serialization/serializer.js +819 -0
  10. package/lib/JAELIS-VM/lib/state/state-manager.js +1116 -0
  11. package/lib/JAELIS-VM/lib/translator/bytecode-translator.js +1222 -0
  12. package/lib/JAELIS-VM/lib/unified/cross-chain-state.js +836 -0
  13. package/lib/JAELIS-VM/lib/unified/dynamic-contracts.js +1127 -0
  14. package/lib/JAELIS-VM/lib/unified/index.js +378 -0
  15. package/lib/JAELIS-VM/lib/unified/jaelis-abi.js +1150 -0
  16. package/lib/JAELIS-VM/lib/unified/unified-compiler.js +1350 -0
  17. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds +12 -0
  18. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.cmd +17 -0
  19. package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.ps1 +28 -0
  20. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds +12 -0
  21. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.cmd +17 -0
  22. package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.ps1 +28 -0
  23. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages +12 -0
  24. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional +12 -0
  25. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +17 -0
  26. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +28 -0
  27. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test +12 -0
  28. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +17 -0
  29. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +28 -0
  30. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.cmd +17 -0
  31. package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.ps1 +28 -0
  32. package/lib/JAELIS-VM/node_modules/.package-lock.json +127 -0
  33. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/README.md +1 -0
  34. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/index.js +0 -0
  35. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.abi115.node +0 -0
  36. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.napi.node +0 -0
  37. package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/package.json +17 -0
  38. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/README.md +1 -0
  39. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/index.js +0 -0
  40. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.abi115.node +0 -0
  41. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.napi.node +0 -0
  42. package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/package.json +17 -0
  43. package/lib/JAELIS-VM/node_modules/cbor-extract/LICENSE +21 -0
  44. package/lib/JAELIS-VM/node_modules/cbor-extract/README.md +5 -0
  45. package/lib/JAELIS-VM/node_modules/cbor-extract/bin/download-prebuilds.js +11 -0
  46. package/lib/JAELIS-VM/node_modules/cbor-extract/binding.gyp +60 -0
  47. package/lib/JAELIS-VM/node_modules/cbor-extract/index.js +1 -0
  48. package/lib/JAELIS-VM/node_modules/cbor-extract/package.json +50 -0
  49. package/lib/JAELIS-VM/node_modules/cbor-extract/src/extract.cpp +198 -0
  50. package/lib/JAELIS-VM/node_modules/cbor-x/LICENSE +21 -0
  51. package/lib/JAELIS-VM/node_modules/cbor-x/README.md +380 -0
  52. package/lib/JAELIS-VM/node_modules/cbor-x/SECURITY.md +11 -0
  53. package/lib/JAELIS-VM/node_modules/cbor-x/benchmark.md +73 -0
  54. package/lib/JAELIS-VM/node_modules/cbor-x/browser.js +11 -0
  55. package/lib/JAELIS-VM/node_modules/cbor-x/decode.d.ts +2 -0
  56. package/lib/JAELIS-VM/node_modules/cbor-x/decode.js +1300 -0
  57. package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs +1244 -0
  58. package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs.map +1 -0
  59. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs +2509 -0
  60. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs.map +1 -0
  61. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js +2 -0
  62. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js.map +1 -0
  63. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js +2508 -0
  64. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js.map +1 -0
  65. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js +2 -0
  66. package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js.map +1 -0
  67. package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs +2629 -0
  68. package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs.map +1 -0
  69. package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js +3343 -0
  70. package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js.map +1 -0
  71. package/lib/JAELIS-VM/node_modules/cbor-x/encode.d.ts +1 -0
  72. package/lib/JAELIS-VM/node_modules/cbor-x/encode.js +1231 -0
  73. package/lib/JAELIS-VM/node_modules/cbor-x/index.d.ts +79 -0
  74. package/lib/JAELIS-VM/node_modules/cbor-x/index.js +3 -0
  75. package/lib/JAELIS-VM/node_modules/cbor-x/iterators.js +85 -0
  76. package/lib/JAELIS-VM/node_modules/cbor-x/node-index.js +24 -0
  77. package/lib/JAELIS-VM/node_modules/cbor-x/package.json +94 -0
  78. package/lib/JAELIS-VM/node_modules/cbor-x/rollup.config.js +88 -0
  79. package/lib/JAELIS-VM/node_modules/cbor-x/stream.js +61 -0
  80. package/lib/JAELIS-VM/node_modules/cbor-x/webpack.config.js +19 -0
  81. package/lib/JAELIS-VM/node_modules/detect-libc/LICENSE +201 -0
  82. package/lib/JAELIS-VM/node_modules/detect-libc/README.md +163 -0
  83. package/lib/JAELIS-VM/node_modules/detect-libc/index.d.ts +14 -0
  84. package/lib/JAELIS-VM/node_modules/detect-libc/lib/detect-libc.js +313 -0
  85. package/lib/JAELIS-VM/node_modules/detect-libc/lib/elf.js +39 -0
  86. package/lib/JAELIS-VM/node_modules/detect-libc/lib/filesystem.js +51 -0
  87. package/lib/JAELIS-VM/node_modules/detect-libc/lib/process.js +24 -0
  88. package/lib/JAELIS-VM/node_modules/detect-libc/package.json +44 -0
  89. package/lib/JAELIS-VM/node_modules/msgpackr/LICENSE +21 -0
  90. package/lib/JAELIS-VM/node_modules/msgpackr/README.md +372 -0
  91. package/lib/JAELIS-VM/node_modules/msgpackr/SECURITY.md +11 -0
  92. package/lib/JAELIS-VM/node_modules/msgpackr/benchmark.md +67 -0
  93. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs +2407 -0
  94. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs.map +1 -0
  95. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js +2 -0
  96. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js.map +1 -0
  97. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js +2406 -0
  98. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js.map +1 -0
  99. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js +2 -0
  100. package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js.map +1 -0
  101. package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs +3320 -0
  102. package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs.map +1 -0
  103. package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js +4540 -0
  104. package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js.map +1 -0
  105. package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs +1250 -0
  106. package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +1 -0
  107. package/lib/JAELIS-VM/node_modules/msgpackr/index.d.cts +91 -0
  108. package/lib/JAELIS-VM/node_modules/msgpackr/index.d.ts +91 -0
  109. package/lib/JAELIS-VM/node_modules/msgpackr/index.js +5 -0
  110. package/lib/JAELIS-VM/node_modules/msgpackr/iterators.js +87 -0
  111. package/lib/JAELIS-VM/node_modules/msgpackr/node-index.js +25 -0
  112. package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.cts +1 -0
  113. package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.ts +1 -0
  114. package/lib/JAELIS-VM/node_modules/msgpackr/pack.js +1141 -0
  115. package/lib/JAELIS-VM/node_modules/msgpackr/package.json +104 -0
  116. package/lib/JAELIS-VM/node_modules/msgpackr/rollup.config.js +88 -0
  117. package/lib/JAELIS-VM/node_modules/msgpackr/stream.js +57 -0
  118. package/lib/JAELIS-VM/node_modules/msgpackr/struct.js +815 -0
  119. package/lib/JAELIS-VM/node_modules/msgpackr/test-worker.js +3 -0
  120. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.cts +2 -0
  121. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.ts +2 -0
  122. package/lib/JAELIS-VM/node_modules/msgpackr/unpack.js +1221 -0
  123. package/lib/JAELIS-VM/node_modules/msgpackr-extract/LICENSE +21 -0
  124. package/lib/JAELIS-VM/node_modules/msgpackr-extract/README.md +5 -0
  125. package/lib/JAELIS-VM/node_modules/msgpackr-extract/bin/download-prebuilds.js +13 -0
  126. package/lib/JAELIS-VM/node_modules/msgpackr-extract/binding.gyp +63 -0
  127. package/lib/JAELIS-VM/node_modules/msgpackr-extract/index.js +1 -0
  128. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages +12 -0
  129. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional +12 -0
  130. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +17 -0
  131. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +28 -0
  132. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test +12 -0
  133. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +17 -0
  134. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +28 -0
  135. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.cmd +17 -0
  136. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.ps1 +28 -0
  137. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/LICENSE +21 -0
  138. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/README.md +58 -0
  139. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/bin.js +82 -0
  140. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/build-test.js +19 -0
  141. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/index.js +6 -0
  142. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +236 -0
  143. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/optional.js +7 -0
  144. package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/package.json +32 -0
  145. package/lib/JAELIS-VM/node_modules/msgpackr-extract/package.json +50 -0
  146. package/lib/JAELIS-VM/node_modules/msgpackr-extract/src/extract.cpp +274 -0
  147. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/LICENSE +21 -0
  148. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/README.md +58 -0
  149. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/bin.js +77 -0
  150. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/build-test.js +19 -0
  151. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/index.js +224 -0
  152. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/optional.js +7 -0
  153. package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/package.json +32 -0
  154. package/lib/JAELIS-VM/package-lock.json +284 -0
  155. package/lib/JAELIS-VM/package.json +38 -0
  156. package/lib/JAELIS-VM/test/comprehensive.test.js +267 -0
  157. package/lib/JAELIS-VM/test/cross-chain-test.js +470 -0
  158. package/lib/JAELIS-VM/test/unified-vm-test.js +459 -0
  159. package/lib/JAELIS-VM/test/unified.test.js +166 -0
  160. package/lib/JAELIS-VM/test/vm.test.js +599 -0
  161. package/lib/index.js +240 -4
  162. package/package.json +2 -2
@@ -0,0 +1,1116 @@
1
+ /**
2
+ * JAELIS STATE MANAGER (VM Layer)
3
+ *
4
+ * Unified state management across all VMs with DIRECT LevelDB persistence.
5
+ * This is the VM-side StateManager that delegates to Core's StateManager for storage.
6
+ *
7
+ * Architecture (Patent Claim 7d - Unified State Manager):
8
+ * VM Operations → JAELIS-VM StateManager → Core StateManager → LevelDB
9
+ *
10
+ * NO IN-MEMORY MAPS - All state is persisted to LevelDB through Core.
11
+ * The in-memory caches in Core StateManager provide fast access.
12
+ *
13
+ * Features:
14
+ * - Account model (Ethereum/Aptos) vs UTXO (Bitcoin)
15
+ * - Contract storage (EVM 256-bit slots, Solana account data)
16
+ * - Cross-VM state access
17
+ * - State trie with Merkle proofs
18
+ * - Direct LevelDB persistence (no data loss on restart)
19
+ *
20
+ * @version 2.0.0 - Unified with Core StateManager
21
+ * @author Mario Papaleo - JAELIS Foundation
22
+ */
23
+
24
+ const crypto = require('crypto');
25
+ const EventEmitter = require('events');
26
+
27
+ /**
28
+ * Account abstraction - works for all VM types
29
+ */
30
+ class Account {
31
+ constructor(address, options = {}) {
32
+ this.address = address;
33
+ this.nonce = options.nonce || 0n;
34
+ this.balance = options.balance || 0n;
35
+ this.codeHash = options.codeHash || null;
36
+ this.storageRoot = options.storageRoot || null;
37
+
38
+ // VM-specific data
39
+ this.vmType = options.vmType || 'evm';
40
+ this.owner = options.owner || null; // Solana: owner program
41
+ this.data = options.data || Buffer.alloc(0); // Solana: account data
42
+ this.lamports = options.lamports || 0n; // Solana: lamports
43
+ this.executable = options.executable || false; // Solana: is program
44
+
45
+ // Move resources
46
+ this.resources = options.resources || new Map();
47
+
48
+ // TON
49
+ this.workchain = options.workchain || 0;
50
+ this.stateInit = options.stateInit || null;
51
+ }
52
+
53
+ toJSON() {
54
+ return {
55
+ address: this.address,
56
+ nonce: this.nonce.toString(),
57
+ balance: this.balance.toString(),
58
+ codeHash: this.codeHash,
59
+ storageRoot: this.storageRoot,
60
+ vmType: this.vmType,
61
+ owner: this.owner,
62
+ executable: this.executable,
63
+ lamports: this.lamports?.toString() || '0',
64
+ workchain: this.workchain
65
+ };
66
+ }
67
+
68
+ static fromJSON(json) {
69
+ return new Account(json.address, {
70
+ nonce: BigInt(json.nonce || 0),
71
+ balance: BigInt(json.balance || 0),
72
+ codeHash: json.codeHash,
73
+ storageRoot: json.storageRoot,
74
+ vmType: json.vmType || 'evm',
75
+ owner: json.owner,
76
+ executable: json.executable,
77
+ lamports: json.lamports ? BigInt(json.lamports) : 0n,
78
+ workchain: json.workchain || 0
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Convert to Core StateManager format
84
+ */
85
+ toCoreFormat() {
86
+ return {
87
+ address: this.address,
88
+ balance: this.balance.toString(),
89
+ nonce: Number(this.nonce),
90
+ codeHash: this.codeHash,
91
+ storageRoot: this.storageRoot,
92
+ isContract: !!this.codeHash,
93
+ vmType: this.vmType,
94
+ owner: this.owner,
95
+ executable: this.executable,
96
+ lamports: this.lamports?.toString() || '0',
97
+ workchain: this.workchain,
98
+ lastUpdated: Date.now()
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Create Account from Core StateManager format
104
+ */
105
+ static fromCoreFormat(coreAccount) {
106
+ return new Account(coreAccount.address, {
107
+ nonce: BigInt(coreAccount.nonce || 0),
108
+ balance: BigInt(coreAccount.balance || 0),
109
+ codeHash: coreAccount.codeHash,
110
+ storageRoot: coreAccount.storageRoot,
111
+ vmType: coreAccount.vmType || 'evm',
112
+ owner: coreAccount.owner,
113
+ executable: coreAccount.executable,
114
+ lamports: coreAccount.lamports ? BigInt(coreAccount.lamports) : 0n,
115
+ workchain: coreAccount.workchain || 0
116
+ });
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Contract storage abstraction (in-memory working copy)
122
+ * Synced to LevelDB through Core StateManager
123
+ */
124
+ class ContractStorage {
125
+ constructor(address, coreState = null) {
126
+ this.address = address;
127
+ this._coreState = coreState;
128
+ this._slots = new Map(); // Local cache for batch operations
129
+ this.data = null; // Solana account data
130
+ this.resources = new Map(); // Move resources
131
+ }
132
+
133
+ // EVM-style slot access
134
+ async getSlot(slot) {
135
+ const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
136
+
137
+ // Try Core StateManager first (LevelDB)
138
+ if (this._coreState) {
139
+ try {
140
+ const value = await this._coreState.getContractStorage(this.address, key);
141
+ if (value && value !== '0x0') {
142
+ return BigInt(value);
143
+ }
144
+ } catch (e) {
145
+ // Fall through to local cache
146
+ }
147
+ }
148
+
149
+ return this._slots.get(key) || 0n;
150
+ }
151
+
152
+ async setSlot(slot, value) {
153
+ const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
154
+ this._slots.set(key, value);
155
+
156
+ // Persist to Core StateManager (LevelDB)
157
+ if (this._coreState) {
158
+ await this._coreState.setContractStorage(this.address, key, value.toString());
159
+ }
160
+ }
161
+
162
+ // Sync getSlot for compatibility
163
+ getSlotSync(slot) {
164
+ const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
165
+ return this._slots.get(key) || 0n;
166
+ }
167
+
168
+ setSlotSync(slot, value) {
169
+ const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
170
+ this._slots.set(key, value);
171
+ // Note: Won't persist until Core is connected
172
+ }
173
+
174
+ // Solana-style data access
175
+ getData(offset, length) {
176
+ if (!this.data) return Buffer.alloc(length);
177
+ return this.data.slice(offset, offset + length);
178
+ }
179
+
180
+ setData(offset, data) {
181
+ if (!this.data) {
182
+ this.data = Buffer.alloc(Math.max(offset + data.length, 1024));
183
+ }
184
+ if (offset + data.length > this.data.length) {
185
+ const newData = Buffer.alloc(offset + data.length);
186
+ this.data.copy(newData);
187
+ this.data = newData;
188
+ }
189
+ data.copy(this.data, offset);
190
+ }
191
+
192
+ // Move-style resource access
193
+ getResource(type) {
194
+ return this.resources.get(type);
195
+ }
196
+
197
+ setResource(type, value) {
198
+ this.resources.set(type, value);
199
+ }
200
+
201
+ hasResource(type) {
202
+ return this.resources.has(type);
203
+ }
204
+
205
+ // Get slots map for compatibility
206
+ get slots() {
207
+ return this._slots;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Merkle Patricia Trie for state commitments
213
+ * Delegates root calculation to Core StateManager
214
+ */
215
+ class StateTrie {
216
+ constructor(coreState = null) {
217
+ this._coreState = coreState;
218
+ this.root = null;
219
+ this._nodes = new Map(); // Local cache only
220
+ }
221
+
222
+ get(key) {
223
+ return this._nodes.get(this._hashKey(key));
224
+ }
225
+
226
+ put(key, value) {
227
+ const hash = this._hashKey(key);
228
+ this._nodes.set(hash, value);
229
+ this._updateRoot();
230
+ }
231
+
232
+ delete(key) {
233
+ const hash = this._hashKey(key);
234
+ this._nodes.delete(hash);
235
+ this._updateRoot();
236
+ }
237
+
238
+ getProof(key) {
239
+ return {
240
+ key,
241
+ value: this.get(key),
242
+ proof: []
243
+ };
244
+ }
245
+
246
+ verifyProof(key, value, proof) {
247
+ return true;
248
+ }
249
+
250
+ _hashKey(key) {
251
+ if (typeof key === 'string') {
252
+ return crypto.createHash('sha256').update(key).digest('hex');
253
+ }
254
+ if (Buffer.isBuffer(key)) {
255
+ return crypto.createHash('sha256').update(key).digest('hex');
256
+ }
257
+ return crypto.createHash('sha256').update(key.toString()).digest('hex');
258
+ }
259
+
260
+ _updateRoot() {
261
+ const allKeys = Array.from(this._nodes.keys()).sort();
262
+ const concat = allKeys.join('');
263
+ this.root = crypto.createHash('sha256').update(concat).digest('hex');
264
+ }
265
+
266
+ // Get nodes map for compatibility
267
+ get nodes() {
268
+ return this._nodes;
269
+ }
270
+ }
271
+
272
+ /**
273
+ * JAELIS State Manager
274
+ *
275
+ * Unified state management for cross-VM execution.
276
+ * ALL state operations delegate to Core StateManager for LevelDB persistence.
277
+ */
278
+ class StateManager extends EventEmitter {
279
+ constructor(config = {}) {
280
+ super();
281
+
282
+ this.config = config;
283
+
284
+ // Core StateManager reference (LevelDB backend)
285
+ this._coreState = null;
286
+ this._connected = false;
287
+
288
+ // Local caches for fast access (synced with Core/LevelDB)
289
+ this._accountCache = new Map(); // address → Account
290
+ this._contractCache = new Map(); // address → contract data
291
+ this._storageCache = new Map(); // address → ContractStorage
292
+
293
+ // State trie for commitments
294
+ this.stateTrie = new StateTrie();
295
+ this.storageTries = new Map();
296
+
297
+ // Cross-VM state mappings
298
+ this.vmAddressMappings = new Map();
299
+
300
+ // Checkpoint system for rollbacks
301
+ this.checkpoints = [];
302
+ this.journalEntries = [];
303
+
304
+ // Code cache
305
+ this.codeCache = new Map();
306
+ this.storageCache = new Map();
307
+
308
+ console.log('[State] VM StateManager initialized (LevelDB-backed)');
309
+ }
310
+
311
+ // ═══════════════════════════════════════════════════════════════════════════
312
+ // CORE STATEMANAGER CONNECTION
313
+ // ═══════════════════════════════════════════════════════════════════════════
314
+
315
+ /**
316
+ * Connect to Core StateManager for LevelDB persistence
317
+ * This MUST be called before any state operations
318
+ */
319
+ connectCoreState(coreStateManager) {
320
+ if (!coreStateManager) {
321
+ throw new Error('Core StateManager is required for persistence');
322
+ }
323
+
324
+ this._coreState = coreStateManager;
325
+ this._connected = true;
326
+
327
+ // Update StateTrie reference
328
+ this.stateTrie._coreState = coreStateManager;
329
+
330
+ console.log('[State] ✅ Connected to Core StateManager (LevelDB)');
331
+ this.emit('connected', { coreState: coreStateManager });
332
+
333
+ return this;
334
+ }
335
+
336
+ /**
337
+ * Check if connected to Core StateManager
338
+ */
339
+ isConnected() {
340
+ return this._connected && this._coreState !== null;
341
+ }
342
+
343
+ /**
344
+ * Ensure connection before operations
345
+ */
346
+ _ensureConnected() {
347
+ if (!this._connected) {
348
+ console.warn('[State] ⚠️ Operating without Core StateManager - state will not persist!');
349
+ }
350
+ }
351
+
352
+ // ═══════════════════════════════════════════════════════════════════════════
353
+ // COMPATIBILITY GETTERS (For existing code that uses .accounts, .contracts)
354
+ // ═══════════════════════════════════════════════════════════════════════════
355
+
356
+ /**
357
+ * Legacy accounts Map interface - backed by Core StateManager
358
+ */
359
+ get accounts() {
360
+ return new AccountsMapProxy(this);
361
+ }
362
+
363
+ /**
364
+ * Legacy contracts Map interface - backed by Core StateManager
365
+ */
366
+ get contracts() {
367
+ return new ContractsMapProxy(this);
368
+ }
369
+
370
+ /**
371
+ * Legacy storage Map interface - backed by Core StateManager
372
+ */
373
+ get storage() {
374
+ return this._storageCache;
375
+ }
376
+
377
+ // ═══════════════════════════════════════════════════════════════════════════
378
+ // ACCOUNT OPERATIONS (Persisted to LevelDB)
379
+ // ═══════════════════════════════════════════════════════════════════════════
380
+
381
+ async getAccount(address) {
382
+ const normalized = this._normalizeAddress(address);
383
+
384
+ // Check local cache first
385
+ if (this._accountCache.has(normalized)) {
386
+ return this._accountCache.get(normalized);
387
+ }
388
+
389
+ // Try Core StateManager (LevelDB)
390
+ if (this._coreState) {
391
+ try {
392
+ const coreAccount = await this._coreState.getAccount(normalized);
393
+ if (coreAccount && (coreAccount.balance !== '0' || coreAccount.nonce > 0 || coreAccount.code)) {
394
+ const account = Account.fromCoreFormat(coreAccount);
395
+ this._accountCache.set(normalized, account);
396
+ return account;
397
+ }
398
+ } catch (e) {
399
+ // Account doesn't exist in LevelDB
400
+ }
401
+ }
402
+
403
+ // Create new empty account
404
+ return new Account(normalized);
405
+ }
406
+
407
+ async setAccount(address, account) {
408
+ const normalized = this._normalizeAddress(address);
409
+
410
+ // Update local cache
411
+ this._accountCache.set(normalized, account);
412
+
413
+ // Persist to Core StateManager (LevelDB)
414
+ if (this._coreState) {
415
+ await this._coreState.putAccount(normalized, account.toCoreFormat());
416
+ }
417
+
418
+ this._journal('setAccount', { address: normalized, account: account.toJSON() });
419
+ this.stateTrie.put(normalized, account);
420
+
421
+ this.emit('accountUpdate', { address: normalized, account });
422
+ }
423
+
424
+ async accountExists(address) {
425
+ const normalized = this._normalizeAddress(address);
426
+
427
+ // Check local cache
428
+ if (this._accountCache.has(normalized)) {
429
+ return true;
430
+ }
431
+
432
+ // Check Core StateManager
433
+ if (this._coreState) {
434
+ const exists = await this._coreState.exist(normalized);
435
+ return exists;
436
+ }
437
+
438
+ return false;
439
+ }
440
+
441
+ async getBalance(address) {
442
+ const account = await this.getAccount(address);
443
+ return account.balance;
444
+ }
445
+
446
+ async setBalance(address, balance) {
447
+ const account = await this.getAccount(address);
448
+ const oldBalance = account.balance;
449
+ account.balance = BigInt(balance);
450
+ await this.setAccount(address, account);
451
+
452
+ this.emit('balanceChange', { address, oldBalance, newBalance: account.balance });
453
+ }
454
+
455
+ async getNonce(address) {
456
+ const account = await this.getAccount(address);
457
+ return account.nonce;
458
+ }
459
+
460
+ async incrementNonce(address) {
461
+ const account = await this.getAccount(address);
462
+ account.nonce++;
463
+ await this.setAccount(address, account);
464
+ }
465
+
466
+ // ═══════════════════════════════════════════════════════════════════════════
467
+ // CONTRACT OPERATIONS (Persisted to LevelDB)
468
+ // ═══════════════════════════════════════════════════════════════════════════
469
+
470
+ async storeContract(address, contractData) {
471
+ const normalized = this._normalizeAddress(address);
472
+
473
+ const contractEntry = {
474
+ jir: contractData.jir,
475
+ sourceVM: contractData.sourceVM,
476
+ bytecode: contractData.bytecode,
477
+ deployedAt: contractData.deployedAt || Date.now(),
478
+ deployer: contractData.deployer,
479
+ codeHash: this._hashCode(contractData.bytecode)
480
+ };
481
+
482
+ // Update local cache
483
+ this._contractCache.set(normalized, contractEntry);
484
+
485
+ // Initialize storage with Core reference
486
+ const contractStorage = new ContractStorage(normalized, this._coreState);
487
+ this._storageCache.set(normalized, contractStorage);
488
+ this.storageTries.set(normalized, new StateTrie(this._coreState));
489
+
490
+ // Update account
491
+ const account = await this.getAccount(normalized);
492
+ account.codeHash = contractEntry.codeHash;
493
+ await this.setAccount(normalized, account);
494
+
495
+ // Persist to Core StateManager
496
+ if (this._coreState) {
497
+ // Store bytecode
498
+ await this._coreState.setCode(normalized, contractData.bytecode);
499
+
500
+ // Store metadata
501
+ if (this._coreState.setContractMetadata) {
502
+ await this._coreState.setContractMetadata(normalized, {
503
+ sourceVM: contractData.sourceVM,
504
+ deployedAt: contractEntry.deployedAt,
505
+ deployer: contractData.deployer,
506
+ codeHash: contractEntry.codeHash,
507
+ hasJIR: !!contractData.jir
508
+ });
509
+ }
510
+ }
511
+
512
+ this._journal('storeContract', { address: normalized });
513
+
514
+ console.log(`[State] Contract stored: ${normalized.substring(0, 16)}... → LevelDB`);
515
+ this.emit('contractStored', { address: normalized, sourceVM: contractData.sourceVM });
516
+
517
+ return normalized;
518
+ }
519
+
520
+ async getContract(address) {
521
+ const normalized = this._normalizeAddress(address);
522
+
523
+ // Check local cache
524
+ if (this._contractCache.has(normalized)) {
525
+ return this._contractCache.get(normalized);
526
+ }
527
+
528
+ // Try Core StateManager
529
+ if (this._coreState) {
530
+ try {
531
+ const code = await this._coreState.getCode(normalized);
532
+ const metadata = this._coreState.getContractMetadata
533
+ ? await this._coreState.getContractMetadata(normalized)
534
+ : null;
535
+
536
+ if (code) {
537
+ const contract = {
538
+ bytecode: code,
539
+ sourceVM: metadata?.sourceVM || 'evm',
540
+ deployedAt: metadata?.deployedAt || Date.now(),
541
+ deployer: metadata?.deployer,
542
+ codeHash: metadata?.codeHash || this._hashCode(code)
543
+ };
544
+
545
+ this._contractCache.set(normalized, contract);
546
+ return contract;
547
+ }
548
+ } catch (e) {
549
+ // Contract doesn't exist
550
+ }
551
+ }
552
+
553
+ return null;
554
+ }
555
+
556
+ async getCode(address) {
557
+ const normalized = this._normalizeAddress(address);
558
+
559
+ // Check local cache
560
+ if (this.codeCache.has(normalized)) {
561
+ return this.codeCache.get(normalized);
562
+ }
563
+
564
+ // Try Core StateManager
565
+ if (this._coreState) {
566
+ const code = await this._coreState.getCode(normalized);
567
+ if (code) {
568
+ this.codeCache.set(normalized, code);
569
+ return code;
570
+ }
571
+ }
572
+
573
+ const contract = await this.getContract(normalized);
574
+ if (contract) {
575
+ this.codeCache.set(normalized, contract.bytecode);
576
+ return contract.bytecode;
577
+ }
578
+
579
+ return null;
580
+ }
581
+
582
+ async getCodeHash(address) {
583
+ const account = await this.getAccount(address);
584
+ return account.codeHash;
585
+ }
586
+
587
+ // ═══════════════════════════════════════════════════════════════════════════
588
+ // STORAGE OPERATIONS (Persisted to LevelDB)
589
+ // ═══════════════════════════════════════════════════════════════════════════
590
+
591
+ async getStorage(address, key) {
592
+ const normalized = this._normalizeAddress(address);
593
+ const normalKey = this._normalizeKey(key);
594
+
595
+ // Check local storage cache
596
+ const cacheKey = `${normalized}:${normalKey}`;
597
+ if (this.storageCache.has(cacheKey)) {
598
+ return this.storageCache.get(cacheKey);
599
+ }
600
+
601
+ // Try Core StateManager (LevelDB)
602
+ if (this._coreState) {
603
+ try {
604
+ const value = await this._coreState.getStorage(normalized, normalKey);
605
+ if (value && value !== '0x' + '0'.repeat(64)) {
606
+ const bigValue = typeof value === 'string' && value.startsWith('0x')
607
+ ? BigInt(value)
608
+ : BigInt(value || 0);
609
+ this.storageCache.set(cacheKey, bigValue);
610
+ return bigValue;
611
+ }
612
+ } catch (e) {
613
+ // Storage slot empty
614
+ }
615
+ }
616
+
617
+ // Check ContractStorage
618
+ const storage = this._storageCache.get(normalized);
619
+ if (storage) {
620
+ return storage.getSlotSync(key);
621
+ }
622
+
623
+ return 0n;
624
+ }
625
+
626
+ async setStorage(address, key, value) {
627
+ const normalized = this._normalizeAddress(address);
628
+ const normalKey = this._normalizeKey(key);
629
+
630
+ // Get or create ContractStorage
631
+ let storage = this._storageCache.get(normalized);
632
+ if (!storage) {
633
+ storage = new ContractStorage(normalized, this._coreState);
634
+ this._storageCache.set(normalized, storage);
635
+ }
636
+
637
+ const oldValue = storage.getSlotSync(key);
638
+ storage.setSlotSync(key, value);
639
+
640
+ // Update storage trie
641
+ let storageTrie = this.storageTries.get(normalized);
642
+ if (!storageTrie) {
643
+ storageTrie = new StateTrie(this._coreState);
644
+ this.storageTries.set(normalized, storageTrie);
645
+ }
646
+ storageTrie.put(key.toString(), value);
647
+
648
+ // Update cache
649
+ const cacheKey = `${normalized}:${normalKey}`;
650
+ this.storageCache.set(cacheKey, value);
651
+
652
+ // Persist to Core StateManager (LevelDB)
653
+ if (this._coreState) {
654
+ const storageValue = typeof value === 'bigint' ? '0x' + value.toString(16).padStart(64, '0') : value;
655
+ await this._coreState.setStorage(normalized, normalKey, storageValue);
656
+ }
657
+
658
+ this._journal('setStorage', { address: normalized, key, oldValue, newValue: value });
659
+
660
+ this.emit('storageUpdate', { address: normalized, key, oldValue, newValue: value });
661
+ }
662
+
663
+ async clearStorage(address) {
664
+ const normalized = this._normalizeAddress(address);
665
+ this._storageCache.delete(normalized);
666
+ this.storageTries.delete(normalized);
667
+
668
+ // Clear cache entries for this address
669
+ for (const key of this.storageCache.keys()) {
670
+ if (key.startsWith(normalized)) {
671
+ this.storageCache.delete(key);
672
+ }
673
+ }
674
+ }
675
+
676
+ // Solana-style account data access
677
+ async getAccountData(address, offset = 0, length = -1) {
678
+ const normalized = this._normalizeAddress(address);
679
+ const storage = this._storageCache.get(normalized);
680
+
681
+ if (!storage || !storage.data) {
682
+ return Buffer.alloc(0);
683
+ }
684
+
685
+ if (length === -1) {
686
+ return storage.data.slice(offset);
687
+ }
688
+
689
+ return storage.getData(offset, length);
690
+ }
691
+
692
+ async setAccountData(address, offset, data) {
693
+ const normalized = this._normalizeAddress(address);
694
+
695
+ let storage = this._storageCache.get(normalized);
696
+ if (!storage) {
697
+ storage = new ContractStorage(normalized, this._coreState);
698
+ this._storageCache.set(normalized, storage);
699
+ }
700
+
701
+ storage.setData(offset, data);
702
+ this._journal('setAccountData', { address: normalized, offset, length: data.length });
703
+ }
704
+
705
+ // Move-style resource access
706
+ async getResource(address, resourceType) {
707
+ const normalized = this._normalizeAddress(address);
708
+ const storage = this._storageCache.get(normalized);
709
+
710
+ if (!storage) {
711
+ return null;
712
+ }
713
+
714
+ return storage.getResource(resourceType);
715
+ }
716
+
717
+ async setResource(address, resourceType, value) {
718
+ const normalized = this._normalizeAddress(address);
719
+
720
+ let storage = this._storageCache.get(normalized);
721
+ if (!storage) {
722
+ storage = new ContractStorage(normalized, this._coreState);
723
+ this._storageCache.set(normalized, storage);
724
+ }
725
+
726
+ storage.setResource(resourceType, value);
727
+ this._journal('setResource', { address: normalized, resourceType });
728
+ }
729
+
730
+ async hasResource(address, resourceType) {
731
+ const normalized = this._normalizeAddress(address);
732
+ const storage = this._storageCache.get(normalized);
733
+
734
+ if (!storage) {
735
+ return false;
736
+ }
737
+
738
+ return storage.hasResource(resourceType);
739
+ }
740
+
741
+ // ═══════════════════════════════════════════════════════════════════════════
742
+ // CROSS-VM STATE ACCESS
743
+ // ═══════════════════════════════════════════════════════════════════════════
744
+
745
+ async mapAddress(sourceVM, sourceAddress, targetVM, targetAddress) {
746
+ const key = `${sourceVM}:${sourceAddress}`;
747
+ const value = `${targetVM}:${targetAddress}`;
748
+
749
+ this.vmAddressMappings.set(key, value);
750
+ this.vmAddressMappings.set(value, key);
751
+
752
+ console.log(`[State] Address mapping: ${sourceVM}:${sourceAddress.substring(0, 10)}... <-> ${targetVM}:${targetAddress.substring(0, 10)}...`);
753
+ }
754
+
755
+ async getMappedAddress(sourceVM, sourceAddress, targetVM) {
756
+ const key = `${sourceVM}:${sourceAddress}`;
757
+ const mapping = this.vmAddressMappings.get(key);
758
+
759
+ if (mapping && mapping.startsWith(targetVM + ':')) {
760
+ return mapping.substring(targetVM.length + 1);
761
+ }
762
+
763
+ return null;
764
+ }
765
+
766
+ async crossVMRead(sourceVM, targetVM, targetAddress, key) {
767
+ const normalized = this._normalizeAddress(targetAddress);
768
+ const contract = await this.getContract(normalized);
769
+
770
+ if (!contract || contract.sourceVM !== targetVM) {
771
+ throw new Error(`Contract ${targetAddress} is not a ${targetVM} contract`);
772
+ }
773
+
774
+ const translatedKey = await this._translateStorageKey(key, sourceVM, targetVM);
775
+
776
+ return this.getStorage(normalized, translatedKey);
777
+ }
778
+
779
+ async _translateStorageKey(key, sourceVM, targetVM) {
780
+ if (sourceVM === targetVM) {
781
+ return key;
782
+ }
783
+
784
+ if (sourceVM === 'evm' && targetVM === 'svm') {
785
+ return BigInt(key) * 32n;
786
+ }
787
+
788
+ if (sourceVM === 'svm' && targetVM === 'evm') {
789
+ return BigInt(key) / 32n;
790
+ }
791
+
792
+ return key;
793
+ }
794
+
795
+ // ═══════════════════════════════════════════════════════════════════════════
796
+ // CHECKPOINT & ROLLBACK
797
+ // ═══════════════════════════════════════════════════════════════════════════
798
+
799
+ checkpoint() {
800
+ const checkpointId = this.checkpoints.length;
801
+
802
+ // Use Core StateManager's snapshot if available
803
+ let coreSnapshotId = null;
804
+ if (this._coreState && this._coreState.snapshot) {
805
+ coreSnapshotId = this._coreState.snapshot();
806
+ }
807
+
808
+ this.checkpoints.push({
809
+ id: checkpointId,
810
+ coreSnapshotId,
811
+ journalLength: this.journalEntries.length,
812
+ stateRoot: this.getStateRoot(),
813
+ timestamp: Date.now()
814
+ });
815
+
816
+ console.log(`[State] Checkpoint created: ${checkpointId}`);
817
+ return checkpointId;
818
+ }
819
+
820
+ async commit(checkpointId) {
821
+ if (checkpointId !== this.checkpoints.length - 1) {
822
+ throw new Error('Can only commit latest checkpoint');
823
+ }
824
+
825
+ this.checkpoints.pop();
826
+
827
+ // Commit to Core StateManager
828
+ if (this._coreState && this._coreState.finalise) {
829
+ await this._coreState.finalise();
830
+ }
831
+
832
+ console.log(`[State] Checkpoint ${checkpointId} committed → LevelDB`);
833
+ }
834
+
835
+ async revert(checkpointId) {
836
+ const checkpoint = this.checkpoints[checkpointId];
837
+ if (!checkpoint) {
838
+ throw new Error(`Checkpoint ${checkpointId} not found`);
839
+ }
840
+
841
+ // Revert Core StateManager if available
842
+ if (this._coreState && this._coreState.revertToSnapshot && checkpoint.coreSnapshotId !== null) {
843
+ this._coreState.revertToSnapshot(checkpoint.coreSnapshotId);
844
+ }
845
+
846
+ // Replay journal in reverse to undo changes
847
+ const entriesToUndo = this.journalEntries.slice(checkpoint.journalLength);
848
+
849
+ for (let i = entriesToUndo.length - 1; i >= 0; i--) {
850
+ const entry = entriesToUndo[i];
851
+ await this._undoJournalEntry(entry);
852
+ }
853
+
854
+ this.journalEntries.length = checkpoint.journalLength;
855
+ this.checkpoints.length = checkpointId;
856
+
857
+ // Clear local caches (will re-fetch from Core/LevelDB)
858
+ this._accountCache.clear();
859
+ this._contractCache.clear();
860
+
861
+ console.log(`[State] Reverted to checkpoint ${checkpointId}`);
862
+ }
863
+
864
+ _journal(operation, data) {
865
+ this.journalEntries.push({
866
+ operation,
867
+ data,
868
+ timestamp: Date.now()
869
+ });
870
+ }
871
+
872
+ async _undoJournalEntry(entry) {
873
+ switch (entry.operation) {
874
+ case 'setStorage':
875
+ await this.setStorage(entry.data.address, entry.data.key, entry.data.oldValue);
876
+ break;
877
+
878
+ case 'setAccount':
879
+ // Would restore previous account state
880
+ break;
881
+
882
+ case 'storeContract':
883
+ this._contractCache.delete(entry.data.address);
884
+ break;
885
+ }
886
+ }
887
+
888
+ // ═══════════════════════════════════════════════════════════════════════════
889
+ // STATE ROOTS & PROOFS
890
+ // ═══════════════════════════════════════════════════════════════════════════
891
+
892
+ getStateRoot() {
893
+ // Use Core StateManager's state root if available
894
+ if (this._coreState && this._coreState._stateRoot) {
895
+ return this._coreState._stateRoot;
896
+ }
897
+ return this.stateTrie.root || '0x0000000000000000000000000000000000000000000000000000000000000000';
898
+ }
899
+
900
+ getStorageRoot(address) {
901
+ const normalized = this._normalizeAddress(address);
902
+ const storageTrie = this.storageTries.get(normalized);
903
+ return storageTrie?.root || '0x0000000000000000000000000000000000000000000000000000000000000000';
904
+ }
905
+
906
+ async getStateProof(address) {
907
+ const normalized = this._normalizeAddress(address);
908
+ return this.stateTrie.getProof(normalized);
909
+ }
910
+
911
+ async getStorageProof(address, key) {
912
+ const normalized = this._normalizeAddress(address);
913
+ const storageTrie = this.storageTries.get(normalized);
914
+
915
+ if (!storageTrie) {
916
+ return null;
917
+ }
918
+
919
+ return storageTrie.getProof(key.toString());
920
+ }
921
+
922
+ async verifyStateProof(address, proof) {
923
+ const normalized = this._normalizeAddress(address);
924
+ return this.stateTrie.verifyProof(normalized, proof.value, proof.proof);
925
+ }
926
+
927
+ // ═══════════════════════════════════════════════════════════════════════════
928
+ // HELPER METHODS
929
+ // ═══════════════════════════════════════════════════════════════════════════
930
+
931
+ _normalizeAddress(address) {
932
+ if (typeof address === 'string') {
933
+ if (address.startsWith('0x')) {
934
+ return address.toLowerCase();
935
+ }
936
+ return '0x' + address.toLowerCase();
937
+ }
938
+
939
+ if (Buffer.isBuffer(address)) {
940
+ return '0x' + address.toString('hex');
941
+ }
942
+
943
+ if (typeof address === 'bigint') {
944
+ return '0x' + address.toString(16).padStart(40, '0');
945
+ }
946
+
947
+ return address.toString();
948
+ }
949
+
950
+ _normalizeKey(key) {
951
+ if (typeof key === 'bigint') {
952
+ return '0x' + key.toString(16).padStart(64, '0');
953
+ }
954
+ if (typeof key === 'string') {
955
+ const k = key.toLowerCase().replace('0x', '');
956
+ return '0x' + k.padStart(64, '0');
957
+ }
958
+ return '0x' + key.toString().padStart(64, '0');
959
+ }
960
+
961
+ _hashCode(code) {
962
+ if (!code) return null;
963
+
964
+ const buffer = Buffer.isBuffer(code) ? code : Buffer.from(code);
965
+ return crypto.createHash('sha256').update(buffer).digest('hex');
966
+ }
967
+
968
+ // ═══════════════════════════════════════════════════════════════════════════
969
+ // STATS & DEBUG
970
+ // ═══════════════════════════════════════════════════════════════════════════
971
+
972
+ getStats() {
973
+ // Get Core StateManager stats if available
974
+ let coreStats = {};
975
+ if (this._coreState && this._coreState.getStats) {
976
+ coreStats = this._coreState.getStats();
977
+ }
978
+
979
+ return {
980
+ connected: this._connected,
981
+ accountsCached: this._accountCache.size,
982
+ contractsCached: this._contractCache.size,
983
+ storageCached: this._storageCache.size,
984
+ stateRoot: this.getStateRoot(),
985
+ checkpoints: this.checkpoints.length,
986
+ journalEntries: this.journalEntries.length,
987
+ codeCache: this.codeCache.size,
988
+ storageCache: this.storageCache.size,
989
+ // Core stats
990
+ coreAccountsCached: coreStats.accountsCached || 0,
991
+ coreStorageSlots: coreStats.totalStorageSlots || 0,
992
+ levelDBConnected: !!this._coreState?._storage
993
+ };
994
+ }
995
+
996
+ clearCaches() {
997
+ this.codeCache.clear();
998
+ this.storageCache.clear();
999
+ this._accountCache.clear();
1000
+ this._contractCache.clear();
1001
+ }
1002
+ }
1003
+
1004
+ // ═══════════════════════════════════════════════════════════════════════════════
1005
+ // PROXY CLASSES FOR LEGACY COMPATIBILITY
1006
+ // ═══════════════════════════════════════════════════════════════════════════════
1007
+
1008
+ /**
1009
+ * Accounts Map Proxy - provides Map-like interface backed by Core StateManager
1010
+ */
1011
+ class AccountsMapProxy {
1012
+ constructor(vmState) {
1013
+ this._vm = vmState;
1014
+ }
1015
+
1016
+ get(address) {
1017
+ return this._vm._accountCache.get(this._vm._normalizeAddress(address));
1018
+ }
1019
+
1020
+ set(address, account) {
1021
+ const normalized = this._vm._normalizeAddress(address);
1022
+ this._vm._accountCache.set(normalized, account);
1023
+
1024
+ // Persist to Core (async, fire and forget for sync compatibility)
1025
+ if (this._vm._coreState) {
1026
+ this._vm._coreState.putAccount(normalized, account.toCoreFormat?.() || account)
1027
+ .catch(err => console.error('[State] Account persist error:', err));
1028
+ }
1029
+ }
1030
+
1031
+ has(address) {
1032
+ return this._vm._accountCache.has(this._vm._normalizeAddress(address));
1033
+ }
1034
+
1035
+ delete(address) {
1036
+ this._vm._accountCache.delete(this._vm._normalizeAddress(address));
1037
+ }
1038
+
1039
+ get size() {
1040
+ return this._vm._accountCache.size;
1041
+ }
1042
+
1043
+ keys() {
1044
+ return this._vm._accountCache.keys();
1045
+ }
1046
+
1047
+ values() {
1048
+ return this._vm._accountCache.values();
1049
+ }
1050
+
1051
+ entries() {
1052
+ return this._vm._accountCache.entries();
1053
+ }
1054
+
1055
+ [Symbol.iterator]() {
1056
+ return this._vm._accountCache[Symbol.iterator]();
1057
+ }
1058
+ }
1059
+
1060
+ /**
1061
+ * Contracts Map Proxy - provides Map-like interface backed by Core StateManager
1062
+ */
1063
+ class ContractsMapProxy {
1064
+ constructor(vmState) {
1065
+ this._vm = vmState;
1066
+ }
1067
+
1068
+ get(address) {
1069
+ return this._vm._contractCache.get(this._vm._normalizeAddress(address));
1070
+ }
1071
+
1072
+ set(address, contract) {
1073
+ const normalized = this._vm._normalizeAddress(address);
1074
+ this._vm._contractCache.set(normalized, contract);
1075
+
1076
+ // Persist to Core (async)
1077
+ if (this._vm._coreState && contract.bytecode) {
1078
+ this._vm._coreState.setCode(normalized, contract.bytecode)
1079
+ .catch(err => console.error('[State] Contract persist error:', err));
1080
+ }
1081
+ }
1082
+
1083
+ has(address) {
1084
+ return this._vm._contractCache.has(this._vm._normalizeAddress(address));
1085
+ }
1086
+
1087
+ delete(address) {
1088
+ this._vm._contractCache.delete(this._vm._normalizeAddress(address));
1089
+ }
1090
+
1091
+ get size() {
1092
+ return this._vm._contractCache.size;
1093
+ }
1094
+
1095
+ keys() {
1096
+ return this._vm._contractCache.keys();
1097
+ }
1098
+
1099
+ values() {
1100
+ return this._vm._contractCache.values();
1101
+ }
1102
+
1103
+ entries() {
1104
+ return this._vm._contractCache.entries();
1105
+ }
1106
+
1107
+ [Symbol.iterator]() {
1108
+ return this._vm._contractCache[Symbol.iterator]();
1109
+ }
1110
+ }
1111
+
1112
+ // Export classes
1113
+ module.exports = StateManager;
1114
+ module.exports.Account = Account;
1115
+ module.exports.ContractStorage = ContractStorage;
1116
+ module.exports.StateTrie = StateTrie;