univo 0.3.0 → 0.3.2

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/dist/cli.mjs CHANGED
@@ -4,8 +4,8 @@ import open from 'open';
4
4
  import { config } from 'dotenv';
5
5
  import { WebSocket } from 'partysocket';
6
6
  import { defineCommand, runMain } from 'citty';
7
- import { h as http } from './shared/univo.TsC-vBTq.mjs';
8
- import { c as createLogger, v as version, n as name } from './shared/univo.CX4GZB_1.mjs';
7
+ import { h as http } from './shared/univo.j1HWrILH.mjs';
8
+ import { c as createLogger, v as version, n as name } from './shared/univo.vwk4Xrn3.mjs';
9
9
 
10
10
  const log = createLogger({ quiet: false });
11
11
  const dev = defineCommand({
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as viem from 'viem';
2
- import { g as getException, c as createException, a as catchException, l as local } from './shared/univo.TsC-vBTq.mjs';
3
- import { c as createLogger, d as decompress, b as decoder, r as retry, v as version, e as normalizeHex, a as isHexEqual, f as compress } from './shared/univo.CX4GZB_1.mjs';
2
+ import { g as getException, c as createException, a as catchException, l as local } from './shared/univo.j1HWrILH.mjs';
3
+ import { c as createLogger, d as decompress, b as decoder, r as retry, v as version, e as normalizeHex, a as isHexEqual, f as compress } from './shared/univo.vwk4Xrn3.mjs';
4
4
  import { AdapterError } from './metadata/adapters.mjs';
5
5
  import 'ws';
6
6
  import 'partysocket';
@@ -139,58 +139,54 @@ function defineIndexer(opts) {
139
139
  const eventsGroupedByStorageMap = /* @__PURE__ */ new Map();
140
140
  const allActions = [];
141
141
  async function getBlockFromChain(head) {
142
- try {
143
- const block = await opts.getBlock({ chain: head.chain, number: head.number });
144
- if (block === null) {
145
- throw new Error("Provided `getBlock` function returned null");
146
- }
147
- if (typeof head.hash === "string") {
148
- if (!isHexEqual(head.hash, block.eth_getBlockByNumber.hash)) {
149
- throw new Error("Method `eth_getBlockByNumber` returned unexpected block hash");
150
- }
151
- }
152
- if (typeof head.parent_hash === "string") {
153
- if (!isHexEqual(head.parent_hash, block.eth_getBlockByNumber.parentHash)) {
154
- throw new Error("Method `eth_getBlockByNumber` returned unexpected parent hash");
155
- }
142
+ return await retry(() => retry_getBlockFromChain(head), 2);
143
+ }
144
+ async function retry_getBlockFromChain(head) {
145
+ const block = await opts.getBlock({ chain: head.chain, number: head.number });
146
+ if (block === null) {
147
+ throw new Error("Provided `getBlock` function returned null");
148
+ }
149
+ if (typeof head.hash === "string") {
150
+ if (!isHexEqual(head.hash, block.eth_getBlockByNumber.hash)) {
151
+ throw new Error("Block returned unexpected block hash");
156
152
  }
157
- verifyBlockHashes(block);
158
- verifyLogIndicies(block);
159
- verifyReceiptsRoot(block);
160
- verifyTransactionsRoot(block);
161
- verifyTransactionIndicies(block);
162
- verifyTransactionGasUsage(block);
163
- return block;
164
- } catch (error) {
165
- if (error instanceof Error) {
166
- log.error(`Failed to load block: ${error.message}`);
153
+ }
154
+ if (typeof head.parent_hash === "string") {
155
+ if (!isHexEqual(head.parent_hash, block.eth_getBlockByNumber.parentHash)) {
156
+ throw new Error("Block returned unexpected parent hash");
167
157
  }
168
- throw error;
169
158
  }
159
+ verifyBlockHashes(block);
160
+ verifyLogIndicies(block);
161
+ verifyReceiptsRoot(block);
162
+ verifyTransactionsRoot(block);
163
+ verifyTransactionIndicies(block);
164
+ verifyTransactionGasUsage(block);
165
+ return block;
170
166
  }
171
167
  function verifyBlockHashes(block) {
172
168
  const blockHash = block.eth_getBlockByNumber.hash;
173
169
  const transactions = block.eth_getBlockByNumber.transactions;
174
170
  for (const transaction of transactions) {
175
171
  if (!isHexEqual(blockHash, transaction.blockHash)) {
176
- throw new Error("Method `eth_getBlockByNumber` returned transaction with unexpected block hash");
172
+ throw new Error("Block returned transaction with unexpected block hash");
177
173
  }
178
174
  }
179
175
  for (const receipt of block.eth_getBlockReceipts) {
180
176
  if (!isHexEqual(block.eth_getBlockByNumber.hash, receipt.blockHash)) {
181
- throw new Error("Method `eth_getBlockReceipts` returned receipt with unexpected block hash");
177
+ throw new Error("Block returned receipt with unexpected block hash");
182
178
  }
183
179
  const transactionIndex = viem.hexToNumber(receipt.transactionIndex);
184
180
  const transaction = transactions[transactionIndex];
185
181
  if (transaction === void 0 || !isHexEqual(transaction.hash, receipt.transactionHash)) {
186
- throw new Error("Method `eth_getBlockReceipts` returned receipt with unexpected transaction hash");
182
+ throw new Error("Block returned receipt with unexpected transaction hash");
187
183
  }
188
184
  for (const entry of receipt.logs) {
189
185
  if (!isHexEqual(blockHash, entry.blockHash)) {
190
- throw new Error("Method `eth_getBlockReceipts` returned log with unexpected block hash");
186
+ throw new Error("Block returned log with unexpected block hash");
191
187
  }
192
188
  if (!isHexEqual(receipt.transactionHash, entry.transactionHash)) {
193
- throw new Error("Method `eth_getBlockReceipts` returned log with unexpected transaction hash");
189
+ throw new Error("Block returned log with unexpected transaction hash");
194
190
  }
195
191
  }
196
192
  }
@@ -200,7 +196,7 @@ function defineIndexer(opts) {
200
196
  for (const receipt of block.eth_getBlockReceipts) {
201
197
  for (const entry of receipt.logs) {
202
198
  if (viem.hexToBigInt(entry.logIndex) !== expectedLogIndex) {
203
- throw new Error("Method `eth_getBlockReceipts` returned non-contiguous log indices");
199
+ throw new Error("Block returned non-contiguous log indices");
204
200
  }
205
201
  expectedLogIndex++;
206
202
  }
@@ -209,7 +205,7 @@ function defineIndexer(opts) {
209
205
  function verifyReceiptsRoot(block) {
210
206
  const receiptsRoot = calculateTrieRoot(block.eth_getBlockReceipts.map(serializeReceipt));
211
207
  if (!isHexEqual(block.eth_getBlockByNumber.receiptsRoot, receiptsRoot)) {
212
- throw new Error("Method `eth_getBlockReceipts` returned receipts that do not match the block receipts root");
208
+ throw new Error("Block returned receipts that do not match the block receipts root");
213
209
  }
214
210
  }
215
211
  function calculateTrieRoot(values) {
@@ -286,6 +282,9 @@ function defineIndexer(opts) {
286
282
  function verifyTransactionsRoot(block) {
287
283
  const transactions = block.eth_getBlockByNumber.transactions.map((transaction) => {
288
284
  const { input, ...formatted } = viem.formatTransaction(transaction);
285
+ if (formatted.type === "legacy" && (formatted.v === 27n || formatted.v === 28n)) {
286
+ formatted.chainId = void 0;
287
+ }
289
288
  const signature = formatted.type === "legacy" ? { r: formatted.r, s: formatted.s, v: formatted.v } : { r: formatted.r, s: formatted.s, yParity: formatted.yParity };
290
289
  const serialized = viem.serializeTransaction(
291
290
  { ...formatted, data: input },
@@ -293,32 +292,32 @@ function defineIndexer(opts) {
293
292
  signature
294
293
  );
295
294
  if (!isHexEqual(transaction.hash, viem.keccak256(serialized))) {
296
- throw new Error("Method `eth_getBlockByNumber` returned transaction with unexpected transaction hash");
295
+ throw new Error(`Transaction ${transaction.hash} failed serialization check`);
297
296
  }
298
297
  return viem.hexToBytes(serialized);
299
298
  });
300
299
  const transactionsRoot = calculateTrieRoot(transactions);
301
300
  if (!isHexEqual(block.eth_getBlockByNumber.transactionsRoot, transactionsRoot)) {
302
- throw new Error("Method `eth_getBlockByNumber` returned transactions that do not match the block transactions root");
301
+ throw new Error("Block returned transactions that do not match the block transactions root");
303
302
  }
304
303
  }
305
304
  function verifyTransactionIndicies(block) {
306
305
  const receipts = block.eth_getBlockReceipts;
307
306
  const transactions = block.eth_getBlockByNumber.transactions;
308
307
  if (transactions.length !== receipts.length) {
309
- throw new Error("Methods `eth_getBlockByNumber` and `eth_getBlockReceipts` returned different transaction counts");
308
+ throw new Error("Block returned different transaction counts");
310
309
  }
311
310
  for (let index = 0; index < transactions.length; index++) {
312
311
  const expectedIndex = BigInt(index);
313
312
  if (viem.hexToBigInt(transactions[index].transactionIndex) !== expectedIndex) {
314
- throw new Error("Method `eth_getBlockByNumber` returned non-contiguous transaction indices");
313
+ throw new Error("Block returned non-contiguous transaction indices");
315
314
  }
316
315
  if (viem.hexToBigInt(receipts[index].transactionIndex) !== expectedIndex) {
317
- throw new Error("Method `eth_getBlockReceipts` returned non-contiguous transaction indices");
316
+ throw new Error("Block returned non-contiguous transaction indices");
318
317
  }
319
318
  for (const entry of receipts[index].logs) {
320
319
  if (viem.hexToBigInt(entry.transactionIndex) !== expectedIndex) {
321
- throw new Error("Method `eth_getBlockReceipts` returned log with unexpected transaction index");
320
+ throw new Error("Block returned log with unexpected transaction index");
322
321
  }
323
322
  }
324
323
  }
@@ -327,20 +326,20 @@ function defineIndexer(opts) {
327
326
  const gasLimit = viem.hexToBigInt(block.eth_getBlockByNumber.gasLimit);
328
327
  const blockGasUsed = viem.hexToBigInt(block.eth_getBlockByNumber.gasUsed);
329
328
  if (blockGasUsed > gasLimit) {
330
- throw new Error("Method `eth_getBlockByNumber` returned gas used greater than the block gas limit");
329
+ throw new Error("Block returned gas used greater than the block gas limit");
331
330
  }
332
331
  let cumulativeGasUsed = 0n;
333
332
  for (const receipt of block.eth_getBlockReceipts) {
334
333
  cumulativeGasUsed += viem.hexToBigInt(receipt.gasUsed);
335
334
  if (viem.hexToBigInt(receipt.cumulativeGasUsed) !== cumulativeGasUsed) {
336
- throw new Error("Method `eth_getBlockReceipts` returned inconsistent cumulative gas used");
335
+ throw new Error("Block returned inconsistent cumulative gas used");
337
336
  }
338
337
  if (cumulativeGasUsed > gasLimit) {
339
- throw new Error("Method `eth_getBlockReceipts` returned cumulative gas used greater than the block gas limit");
338
+ throw new Error("Block returned cumulative gas used greater than the block gas limit");
340
339
  }
341
340
  }
342
341
  if (cumulativeGasUsed !== blockGasUsed) {
343
- throw new Error("Methods `eth_getBlockByNumber` and `eth_getBlockReceipts` returned inconsistent gas used");
342
+ throw new Error("Block returned inconsistent gas used");
344
343
  }
345
344
  }
346
345
  async function getOrInitManifest(chain) {
@@ -406,7 +405,8 @@ function defineIndexer(opts) {
406
405
  const number = normalizeHex(block.eth_getBlockByNumber.number, 16);
407
406
  const parentHash = normalizeHex(block.eth_getBlockByNumber.parentHash);
408
407
  const commitsKey = `commits/v1/${chain}/${number}/${hash}/${parentHash}`;
409
- await opts.metadataStorage.adapter.put(commitsKey, "commitsValue");
408
+ const commitsValue = JSON.stringify({ hello: "world" });
409
+ await opts.metadataStorage.adapter.put(commitsKey, commitsValue);
410
410
  }
411
411
  const public_writeUnfinalizedHead = async (head) => {
412
412
  log.debug("Received unfinalized head...");
@@ -428,9 +428,7 @@ function defineIndexer(opts) {
428
428
  const parentHash = normalizeHex(block.eth_getBlockByNumber.parentHash);
429
429
  const blocksKey = `blocks/v1/${chain}/${number}/${hash}/${parentHash}`;
430
430
  const blocksValue = await compress(JSON.stringify(block));
431
- const conditional = {
432
- ifNoneMatch: "*"
433
- };
431
+ const conditional = { ifNoneMatch: "*" };
434
432
  const result = await opts.metadataStorage.adapter.put(blocksKey, blocksValue, conditional).catch((error) => {
435
433
  if (error instanceof AdapterError) {
436
434
  if (error.tag === "PreconditionFailed") {
@@ -540,7 +538,8 @@ function defineIndexer(opts) {
540
538
  throw failure.reason;
541
539
  }
542
540
  const commitsKey = `${prefix}/action/${action2.id}`;
543
- await opts.metadataStorage.adapter.put(commitsKey, "");
541
+ const commitsValue = JSON.stringify({ hello: "world" });
542
+ await opts.metadataStorage.adapter.put(commitsKey, commitsValue);
544
543
  });
545
544
  await Promise.all(promises);
546
545
  }
@@ -570,7 +569,9 @@ function defineIndexer(opts) {
570
569
  const hash = normalizeHex(block.eth_getBlockByNumber.hash);
571
570
  const parentHash = normalizeHex(block.eth_getBlockByNumber.parentHash);
572
571
  const finalizedKey = `finalized/v1/${chain}/${number}/${hash}/${parentHash}`;
573
- const result = await opts.metadataStorage.adapter.put(finalizedKey, "", { ifNoneMatch: "*" }).catch((error) => {
572
+ const finalizedValue = JSON.stringify({ hello: "world" });
573
+ const conditional = { ifNoneMatch: "*" };
574
+ const result = await opts.metadataStorage.adapter.put(finalizedKey, finalizedValue, conditional).catch((error) => {
574
575
  if (error instanceof AdapterError && error.tag === "PreconditionFailed") {
575
576
  return null;
576
577
  }
package/dist/realtime.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { hexToNumber } from 'viem';
2
- import { c as createLogger, i as iife, m as mutex, r as retry, a as isHexEqual } from './shared/univo.CX4GZB_1.mjs';
2
+ import { c as createLogger, i as iife, m as mutex, r as retry, a as isHexEqual } from './shared/univo.vwk4Xrn3.mjs';
3
3
 
4
4
  function defineBlockchain(opts) {
5
5
  const log = createLogger({ quiet: opts.quiet });
@@ -122,7 +122,7 @@ function realtime(opts) {
122
122
  await retry(
123
123
  () => opts.indexer.request({ method: "public_deleteReorganisedHead", params: [{ chain, ...head }] }),
124
124
  //
125
- 4
125
+ 2
126
126
  );
127
127
  log.debug("Delivered reorganised head");
128
128
  } catch (error) {
@@ -145,37 +145,6 @@ function realtime(opts) {
145
145
  });
146
146
  });
147
147
  log.debug("Subscribed unfinalized chain to new heads");
148
- let chainFinalizedHeight = hexToNumber(chainFinalizedBlock.number);
149
- async function writeFinalizedHead(nextFinalizedBlock) {
150
- const nextFinalizedHeight = hexToNumber(nextFinalizedBlock.number);
151
- const newFinalizedHeads = unfinalized.chain.filter((head) => {
152
- if (hexToNumber(head.number) > chainFinalizedHeight && hexToNumber(head.number) <= nextFinalizedHeight) {
153
- return true;
154
- }
155
- return false;
156
- }).map((head) => {
157
- return { chain, ...head };
158
- });
159
- if (newFinalizedHeads.length === 0) {
160
- return log.debug("No new finalized heads to process");
161
- }
162
- log.debug(`Processing ${newFinalizedHeads.length} finalized head(s) in parallel`);
163
- const promises = newFinalizedHeads.map(async (head) => {
164
- try {
165
- log.debug("Received finalized head");
166
- await opts.indexer.request({ params: [head], method: "public_writeFinalizedHead" });
167
- log.debug("Delivered finalized head");
168
- } catch (error) {
169
- if (error instanceof Error) {
170
- log.warn(`Failed to write finalized head: ${error.message}`);
171
- }
172
- }
173
- });
174
- await Promise.allSettled(promises);
175
- log.debug(`Processed ${newFinalizedHeads.length} finalized head(s) in parallel`);
176
- chainFinalizedHeight = nextFinalizedHeight;
177
- await unfinalized.prune(nextFinalizedBlock);
178
- }
179
148
  async function finalize() {
180
149
  try {
181
150
  log.debug("Finalizing indexer...");
@@ -183,11 +152,12 @@ function realtime(opts) {
183
152
  log.debug("Indexer finalized");
184
153
  } catch (error) {
185
154
  if (error instanceof Error) {
186
- log.warn(`Failed to write unfinalized heads ${error.message}`);
155
+ log.warn(`Failed to finalize: ${error.message}`);
187
156
  }
188
157
  }
189
158
  }
190
159
  const mutex_finalize = mutex(finalize);
160
+ let chainFinalizedHeight = hexToNumber(chainFinalizedBlock.number);
191
161
  async function poll() {
192
162
  try {
193
163
  log.debug("Polling for finalized height...");
@@ -195,7 +165,34 @@ function realtime(opts) {
195
165
  method: "eth_getBlockByNumber",
196
166
  params: ["finalized", false]
197
167
  });
198
- await writeFinalizedHead({
168
+ const nextFinalizedHeight = hexToNumber(finalizedBlock.number);
169
+ const newFinalizedHeads = unfinalized.chain.filter((head) => {
170
+ if (hexToNumber(head.number) > chainFinalizedHeight && hexToNumber(head.number) <= nextFinalizedHeight) {
171
+ return true;
172
+ }
173
+ return false;
174
+ }).map((head) => {
175
+ return { chain, ...head };
176
+ });
177
+ if (newFinalizedHeads.length === 0) {
178
+ return log.debug("No new finalized heads to process");
179
+ }
180
+ log.debug(`Processing ${newFinalizedHeads.length} finalized head(s) in parallel`);
181
+ const promises = newFinalizedHeads.map(async (head) => {
182
+ try {
183
+ log.debug("Received finalized head");
184
+ await opts.indexer.request({ params: [head], method: "public_writeFinalizedHead" });
185
+ log.debug("Delivered finalized head");
186
+ } catch (error) {
187
+ if (error instanceof Error) {
188
+ log.warn(`Failed to write finalized head: ${error.message}`);
189
+ }
190
+ }
191
+ });
192
+ await Promise.allSettled(promises);
193
+ log.debug(`Processed ${newFinalizedHeads.length} finalized head(s) in parallel`);
194
+ chainFinalizedHeight = nextFinalizedHeight;
195
+ await unfinalized.prune({
199
196
  hash: finalizedBlock.hash,
200
197
  number: finalizedBlock.number,
201
198
  parent_hash: finalizedBlock.parentHash
@@ -1,6 +1,6 @@
1
1
  import ws from 'ws';
2
2
  import { WebSocket } from 'partysocket';
3
- import { f as compress, g as raise, c as createLogger, m as mutex } from './univo.CX4GZB_1.mjs';
3
+ import { f as compress, g as raise, c as createLogger, m as mutex } from './univo.vwk4Xrn3.mjs';
4
4
 
5
5
  function createException(message) {
6
6
  return `univo:${message}`;
@@ -1,5 +1,5 @@
1
1
  const name = "univo";
2
- const version = "0.3.0";
2
+ const version = "0.3.2";
3
3
 
4
4
  function createLogger(opts) {
5
5
  let prefix = `[${name}@${version}]`;
@@ -1,4 +1,4 @@
1
1
  import 'ws';
2
2
  import 'partysocket';
3
- export { h as http, l as local, w as wss } from './shared/univo.TsC-vBTq.mjs';
4
- import './shared/univo.CX4GZB_1.mjs';
3
+ export { h as http, l as local, w as wss } from './shared/univo.j1HWrILH.mjs';
4
+ import './shared/univo.vwk4Xrn3.mjs';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "univo",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "0.3.0",
5
+ "version": "0.3.2",
6
6
  "sideEffects": false,
7
7
  "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",