@aztec/aztec-node 0.7.10 → 0.8.6

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 (38) hide show
  1. package/README.md +1 -1
  2. package/dest/aztec-node/config.d.ts +4 -1
  3. package/dest/aztec-node/config.d.ts.map +1 -1
  4. package/dest/aztec-node/config.js +3 -1
  5. package/dest/aztec-node/db.d.ts +13 -0
  6. package/dest/aztec-node/db.d.ts.map +1 -0
  7. package/dest/aztec-node/db.js +43 -0
  8. package/dest/aztec-node/http_rpc_server.d.ts +9 -0
  9. package/dest/aztec-node/http_rpc_server.d.ts.map +1 -0
  10. package/dest/aztec-node/http_rpc_server.js +30 -0
  11. package/dest/aztec-node/server.d.ts +35 -44
  12. package/dest/aztec-node/server.d.ts.map +1 -1
  13. package/dest/aztec-node/server.js +74 -70
  14. package/dest/bin/index.d.ts +9 -0
  15. package/dest/bin/index.d.ts.map +1 -0
  16. package/dest/bin/index.js +53 -0
  17. package/dest/index.d.ts +1 -1
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +2 -2
  20. package/package.json +66 -11
  21. package/src/aztec-node/config.ts +8 -1
  22. package/src/aztec-node/db.ts +60 -0
  23. package/src/aztec-node/http_rpc_server.ts +46 -0
  24. package/src/aztec-node/server.ts +70 -75
  25. package/src/bin/index.ts +67 -0
  26. package/src/index.ts +1 -1
  27. package/.dockerignore +0 -4
  28. package/.eslintrc.cjs +0 -1
  29. package/.tsbuildinfo +0 -1
  30. package/dest/aztec-node/http-node.d.ts +0 -149
  31. package/dest/aztec-node/http-node.d.ts.map +0 -1
  32. package/dest/aztec-node/http-node.js +0 -334
  33. package/dest/aztec-node/http-node.test.d.ts +0 -2
  34. package/dest/aztec-node/http-node.test.d.ts.map +0 -1
  35. package/dest/aztec-node/http-node.test.js +0 -386
  36. package/src/aztec-node/http-node.test.ts +0 -519
  37. package/src/aztec-node/http-node.ts +0 -388
  38. package/tsconfig.json +0 -38
@@ -1,386 +0,0 @@
1
- import { AztecAddress, CircuitsWasm, EthAddress, Fr, FunctionSelector, HistoricBlockData } from '@aztec/circuits.js';
2
- import { randomBytes } from '@aztec/foundation/crypto';
3
- import { Pedersen } from '@aztec/merkle-tree';
4
- import { ContractData, ExtendedContractData, L1ToL2Message, L2Block, L2BlockL2Logs, LogType, MerkleTreeId, SiblingPath, SimulationError, TxHash, mockTx, } from '@aztec/types';
5
- import { jest } from '@jest/globals';
6
- import { HttpNode } from './http-node.js';
7
- const TEST_URL = 'http://aztec-node-url.com/';
8
- const setFetchMock = (response, status = 200) => {
9
- global.fetch = jest
10
- .fn()
11
- .mockImplementation((_input, _init) => {
12
- return Promise.resolve({
13
- status,
14
- ok: true,
15
- json: () => response,
16
- arrayBuffer: () => response,
17
- });
18
- });
19
- };
20
- describe('HttpNode', () => {
21
- let httpNode;
22
- let pedersen;
23
- beforeAll(async () => {
24
- httpNode = new HttpNode(TEST_URL);
25
- pedersen = new Pedersen(await CircuitsWasm.get());
26
- });
27
- afterEach(() => {
28
- jest.clearAllMocks();
29
- });
30
- describe('isReady', () => {
31
- it.each([true, false])('should return %s when the node is ready', async () => {
32
- const response = { isReady: true };
33
- setFetchMock(response);
34
- const result = await httpNode.isReady();
35
- expect(fetch).toHaveBeenCalledWith(TEST_URL);
36
- expect(result).toBe(true);
37
- });
38
- });
39
- describe('getBlocks', () => {
40
- it('should fetch and parse blocks', async () => {
41
- const block1 = L2Block.random(1);
42
- const block2 = L2Block.random(2);
43
- const response = {
44
- blocks: [block1.encode(), block2.encode()],
45
- };
46
- setFetchMock(response);
47
- const result = await httpNode.getBlocks(0, 3);
48
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-blocks?from=0&limit=3`);
49
- expect(result).toEqual([block1, block2]);
50
- });
51
- it('should return an empty array if blocks are not available', async () => {
52
- const response = { blocks: [] };
53
- setFetchMock(response);
54
- const result = await httpNode.getBlocks(0, 2);
55
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-blocks?from=0&limit=2`);
56
- expect(result).toEqual([]);
57
- });
58
- });
59
- describe('getBlock', () => {
60
- it('should fetch and parse a block', async () => {
61
- const block1 = L2Block.random(1);
62
- const response = {
63
- block: block1.encode(),
64
- };
65
- setFetchMock(response);
66
- const result = await httpNode.getBlock(1);
67
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-block?number=1`);
68
- expect(result).toEqual(block1);
69
- });
70
- it('should return undefined if the block is not available', async () => {
71
- const response = { block: undefined };
72
- setFetchMock(response);
73
- const result = await httpNode.getBlock(2);
74
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-block?number=2`);
75
- expect(result).toEqual(undefined);
76
- });
77
- });
78
- describe('getBlockNumber', () => {
79
- it('should fetch and return current block number', async () => {
80
- const response = { blockNumber: 100 };
81
- setFetchMock(response);
82
- const result = await httpNode.getBlockNumber();
83
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-block-number`);
84
- expect(result).toBe(100);
85
- });
86
- });
87
- describe('getVersion', () => {
88
- it('should fetch and return the version', async () => {
89
- const response = { version: 5 };
90
- setFetchMock(response);
91
- const result = await httpNode.getVersion();
92
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-version`);
93
- expect(result).toBe(5);
94
- });
95
- });
96
- describe('getChainId', () => {
97
- it('should fetch and return the chain ID', async () => {
98
- const response = { chainId: 1234 };
99
- setFetchMock(response);
100
- const result = await httpNode.getChainId();
101
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-chain-id`);
102
- expect(result).toBe(1234);
103
- });
104
- });
105
- describe('getRollupAddress', () => {
106
- it('should fetch and return the rollup address', async () => {
107
- const addr = EthAddress.random();
108
- const response = { rollupAddress: addr.toString() };
109
- setFetchMock(response);
110
- const result = await httpNode.getRollupAddress();
111
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-rollup-address`);
112
- expect(result).toEqual(addr);
113
- });
114
- });
115
- describe('getExtendedContractData', () => {
116
- it('should fetch and return contract public data', async () => {
117
- const extendedContractData = ExtendedContractData.random();
118
- const response = {
119
- contractData: extendedContractData.toBuffer(),
120
- };
121
- setFetchMock(response);
122
- const result = await httpNode.getExtendedContractData(extendedContractData.contractData.contractAddress);
123
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-data-and-bytecode?address=${extendedContractData.contractData.contractAddress.toString()}`);
124
- expect(result).toEqual(extendedContractData);
125
- });
126
- it('should return undefined if contract data is not available', async () => {
127
- const response = {
128
- contractData: undefined,
129
- };
130
- setFetchMock(response);
131
- const randomAddress = AztecAddress.random();
132
- const result = await httpNode.getExtendedContractData(randomAddress);
133
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-data-and-bytecode?address=${randomAddress.toString()}`);
134
- expect(result).toEqual(undefined);
135
- });
136
- });
137
- describe('getLogs', () => {
138
- it.each(['encrypted', 'unencrypted'])('should fetch and return %s logs', async (logType) => {
139
- const processedLogType = logType === 'encrypted' ? LogType.ENCRYPTED : LogType.UNENCRYPTED;
140
- const from = 0;
141
- const limit = 3;
142
- const log1 = L2BlockL2Logs.random(2, 3, 4);
143
- const log2 = L2BlockL2Logs.random(1, 5, 2);
144
- const response = {
145
- logs: [log1.toBuffer(), log2.toBuffer()],
146
- };
147
- setFetchMock(response);
148
- const result = await httpNode.getLogs(from, limit, processedLogType);
149
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-logs?from=${from}&limit=${limit}&logType=${processedLogType}`);
150
- expect(result).toEqual([log1, log2]);
151
- });
152
- it.each(['encrypted', 'unencrypted'])('should return an empty array if %s logs are not available', async (logType) => {
153
- const processedLogType = logType === 'encrypted' ? LogType.ENCRYPTED : LogType.UNENCRYPTED;
154
- const from = 0;
155
- const limit = 2;
156
- const response = {};
157
- setFetchMock(response);
158
- const result = await httpNode.getLogs(from, limit, processedLogType);
159
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-logs?from=${from}&limit=${limit}&logType=${processedLogType}`);
160
- expect(result).toEqual([]);
161
- });
162
- });
163
- describe('getContractData', () => {
164
- it('should fetch and return contract data', async () => {
165
- const contractData = ContractData.random();
166
- const response = {
167
- contractData: contractData.toBuffer(),
168
- };
169
- setFetchMock(response);
170
- const result = await httpNode.getContractData(contractData.contractAddress);
171
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-data?address=${contractData.contractAddress.toString()}`);
172
- expect(result).toEqual(contractData);
173
- });
174
- it('should return undefined if contract data is not available', async () => {
175
- const response = {
176
- contractData: undefined,
177
- };
178
- setFetchMock(response);
179
- const randomAddress = AztecAddress.random();
180
- const result = await httpNode.getContractData(randomAddress);
181
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-data?address=${randomAddress.toString()}`);
182
- expect(result).toBeUndefined();
183
- });
184
- });
185
- describe('sendTx', () => {
186
- it('should submit a transaction to the p2p pool', async () => {
187
- const tx = mockTx();
188
- const irrelevantResponse = {};
189
- setFetchMock(irrelevantResponse);
190
- await httpNode.sendTx(tx);
191
- const init = {
192
- method: 'POST',
193
- body: tx.toBuffer(),
194
- };
195
- const call = fetch.mock.calls[0];
196
- expect(call[0].href).toBe(`${TEST_URL}tx`);
197
- expect(call[1]).toStrictEqual(init);
198
- });
199
- });
200
- describe('getPendingTxByHash', () => {
201
- it('should fetch and return a pending tx', async () => {
202
- const txHash = new TxHash(randomBytes(TxHash.SIZE));
203
- const tx = mockTx();
204
- const response = tx.toBuffer();
205
- setFetchMock(response);
206
- const result = await httpNode.getPendingTxByHash(txHash);
207
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-pending-tx?hash=${txHash}`);
208
- expect(result).toEqual(tx);
209
- });
210
- it('should return undefined if the pending tx does not exist', async () => {
211
- const txHash = new TxHash(randomBytes(TxHash.SIZE));
212
- const response = undefined;
213
- setFetchMock(response, 404);
214
- const result = await httpNode.getPendingTxByHash(txHash);
215
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}get-pending-tx?hash=${txHash}`);
216
- expect(result).toBeUndefined();
217
- });
218
- });
219
- describe('findContractIndex', () => {
220
- it('should fetch and return the index of the given contract', async () => {
221
- const leafValue = Buffer.from('abc123', 'hex');
222
- const index = '123456';
223
- const response = { index };
224
- setFetchMock(response);
225
- const result = await httpNode.findContractIndex(leafValue);
226
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-index?leaf=${leafValue.toString('hex')}`);
227
- expect(result).toBe(BigInt(index));
228
- });
229
- it('should return undefined if the contract index is not found', async () => {
230
- const leafValue = Buffer.from('def456', 'hex');
231
- const response = {};
232
- setFetchMock(response);
233
- const result = await httpNode.findContractIndex(leafValue);
234
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-index?leaf=${leafValue.toString('hex')}`);
235
- expect(result).toBeUndefined();
236
- });
237
- });
238
- describe('getContractPath', () => {
239
- it('should fetch and return the sibling path for the given leaf index', async () => {
240
- const leafIndex = BigInt(123456);
241
- const siblingPath = SiblingPath.ZERO(3, Buffer.alloc(32), pedersen);
242
- const response = { path: siblingPath.toBuffer().toString('hex') };
243
- setFetchMock(response);
244
- const result = await httpNode.getContractPath(leafIndex);
245
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}contract-path?leaf=${leafIndex.toString()}`);
246
- expect(result).toEqual(siblingPath);
247
- });
248
- });
249
- describe('findCommitmentIndex', () => {
250
- it('should fetch and return the index of the given leaf', async () => {
251
- const leafValue = Buffer.from('0123456789', 'hex');
252
- const expectedIndex = BigInt(123);
253
- const response = { index: expectedIndex.toString() };
254
- setFetchMock(response);
255
- const result = await httpNode.findCommitmentIndex(leafValue);
256
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}commitment-index?leaf=${leafValue.toString('hex')}`);
257
- expect(result).toBe(expectedIndex);
258
- });
259
- it('should return undefined if the commitment index is not found', async () => {
260
- const leafValue = Buffer.from('def456', 'hex');
261
- const response = {};
262
- setFetchMock(response);
263
- const result = await httpNode.findCommitmentIndex(leafValue);
264
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}commitment-index?leaf=${leafValue.toString('hex')}`);
265
- expect(result).toBeUndefined();
266
- });
267
- });
268
- describe('getDataTreePath', () => {
269
- it('should fetch and return the sibling path for the given leaf index', async () => {
270
- const leafIndex = BigInt(123456);
271
- const siblingPath = SiblingPath.ZERO(3, Buffer.alloc(32), pedersen);
272
- const response = { path: siblingPath.toBuffer().toString('hex') };
273
- setFetchMock(response);
274
- const result = await httpNode.getDataTreePath(leafIndex);
275
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}data-path?leaf=${leafIndex.toString()}`);
276
- expect(result).toEqual(siblingPath);
277
- });
278
- });
279
- describe('getL1ToL2MessageAndIndex', () => {
280
- it('should fetch and return the L1 to L2 message and index for the given message key', async () => {
281
- const messageKey = new Fr(789);
282
- const expectedMessage = L1ToL2Message.random();
283
- const expectedIndex = BigInt(123);
284
- const response = { message: expectedMessage.toBuffer().toString('hex'), index: expectedIndex.toString() };
285
- setFetchMock(response);
286
- const result = await httpNode.getL1ToL2MessageAndIndex(messageKey);
287
- expect(fetch).toHaveBeenCalledWith(`${TEST_URL}l1-l2-message?messageKey=${messageKey.toString()}`);
288
- expect(result).toEqual({
289
- message: expectedMessage,
290
- index: expectedIndex,
291
- });
292
- });
293
- });
294
- describe('getL1ToL2MessagesTreePath', () => {
295
- it('should fetch and return the sibling path for the given leaf index', async () => {
296
- const leafIndex = BigInt(123456);
297
- const siblingPath = SiblingPath.ZERO(3, Buffer.alloc(32), pedersen);
298
- const response = { path: siblingPath.toBuffer().toString('hex') };
299
- setFetchMock(response);
300
- const result = await httpNode.getL1ToL2MessagesTreePath(leafIndex);
301
- const url = `${TEST_URL}l1-l2-path?leaf=${leafIndex.toString()}`;
302
- expect(fetch).toHaveBeenCalledWith(url);
303
- expect(result).toEqual(siblingPath);
304
- });
305
- });
306
- describe('getPublicStorageAt', () => {
307
- it('should fetch and return the storage value at the given contract slot', async () => {
308
- const contractAddress = AztecAddress.random();
309
- const slot = BigInt(789);
310
- const storageValue = Buffer.from('0123456789', 'hex');
311
- const response = { value: storageValue.toString('hex') };
312
- setFetchMock(response);
313
- const result = await httpNode.getPublicStorageAt(contractAddress, slot);
314
- const url = `${TEST_URL}public-storage-at?address=${contractAddress}&slot=${slot.toString()}`;
315
- expect(fetch).toHaveBeenCalledWith(url);
316
- expect(result).toEqual(storageValue);
317
- });
318
- it('should return undefined if the storage value is not found', async () => {
319
- const contractAddress = AztecAddress.random();
320
- const slot = BigInt(987);
321
- const response = {};
322
- setFetchMock(response);
323
- const result = await httpNode.getPublicStorageAt(contractAddress, slot);
324
- const url = `${TEST_URL}public-storage-at?address=${contractAddress}&slot=${slot.toString()}`;
325
- expect(fetch).toHaveBeenCalledWith(url);
326
- expect(result).toBeUndefined();
327
- });
328
- });
329
- describe('getTreeRoots', () => {
330
- it('should fetch and return the current committed roots for the data trees', async () => {
331
- const roots = {
332
- [MerkleTreeId.CONTRACT_TREE]: Fr.random(),
333
- [MerkleTreeId.PRIVATE_DATA_TREE]: Fr.random(),
334
- [MerkleTreeId.NULLIFIER_TREE]: Fr.random(),
335
- [MerkleTreeId.PUBLIC_DATA_TREE]: Fr.random(),
336
- [MerkleTreeId.L1_TO_L2_MESSAGES_TREE]: Fr.random(),
337
- [MerkleTreeId.BLOCKS_TREE]: Fr.random(),
338
- };
339
- const rootsInResponse = Object.fromEntries(Object.entries(roots).map(([key, value]) => [key, value.toString()]));
340
- const response = { roots: rootsInResponse };
341
- setFetchMock(response);
342
- const result = await httpNode.getTreeRoots();
343
- const url = `${TEST_URL}tree-roots`;
344
- expect(fetch).toHaveBeenCalledWith(url);
345
- expect(result).toEqual(roots);
346
- });
347
- });
348
- describe('getHistoricBlockData', () => {
349
- it('should fetch and return the current committed roots for the data trees', async () => {
350
- const blockData = HistoricBlockData.random();
351
- const response = { blockData };
352
- setFetchMock(response);
353
- const result = await httpNode.getHistoricBlockData();
354
- const url = `${TEST_URL}historic-block-data`;
355
- expect(fetch).toHaveBeenCalledWith(url);
356
- expect(result).toEqual(blockData);
357
- });
358
- });
359
- describe('simulatePublicCalls', () => {
360
- it('should fetch a successful simulation response', async () => {
361
- const tx = mockTx();
362
- const response = {};
363
- setFetchMock(response);
364
- await httpNode.simulatePublicCalls(tx);
365
- const init = {
366
- method: 'POST',
367
- body: tx.toBuffer(),
368
- };
369
- const call = fetch.mock.calls[0];
370
- expect(call[0].href).toBe(`${TEST_URL}simulate-tx`);
371
- expect(call[1]).toStrictEqual(init);
372
- });
373
- it('should fetch a simulation error', async () => {
374
- const tx = mockTx();
375
- const simulationError = new SimulationError('test error', [
376
- { contractAddress: AztecAddress.ZERO, functionSelector: FunctionSelector.empty() },
377
- ]);
378
- const response = {
379
- simulationError: simulationError.toJSON(),
380
- };
381
- setFetchMock(response);
382
- await expect(httpNode.simulatePublicCalls(tx)).rejects.toThrow(simulationError);
383
- });
384
- });
385
- });
386
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1ub2RlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXp0ZWMtbm9kZS9odHRwLW5vZGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckgsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQ0wsWUFBWSxFQUNaLG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsT0FBTyxFQUNQLGFBQWEsRUFDYixPQUFPLEVBQ1AsWUFBWSxFQUNaLFdBQVcsRUFDWCxlQUFlLEVBQ2YsTUFBTSxFQUNOLE1BQU0sR0FDUCxNQUFNLGNBQWMsQ0FBQztBQUV0QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUxQyxNQUFNLFFBQVEsR0FBRyw0QkFBNEIsQ0FBQztBQUU5QyxNQUFNLFlBQVksR0FBRyxDQUFDLFFBQWEsRUFBRSxNQUFNLEdBQUcsR0FBRyxFQUFRLEVBQUU7SUFDekQsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJO1NBQ2hCLEVBQUUsRUFBdUI7U0FDekIsa0JBQWtCLENBQUMsQ0FBQyxNQUF5QixFQUFFLEtBQStCLEVBQUUsRUFBRTtRQUNqRixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDckIsTUFBTTtZQUNOLEVBQUUsRUFBRSxJQUFJO1lBQ1IsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVE7WUFDcEIsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVE7U0FDaEIsQ0FBQyxDQUFDO0lBQ2pCLENBQUMsQ0FBQyxD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