univo 0.4.0 → 0.4.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
@@ -5,7 +5,7 @@ import { config } from 'dotenv';
5
5
  import { WebSocket } from 'partysocket';
6
6
  import { defineCommand, runMain } from 'citty';
7
7
  import { http } from './transport.mjs';
8
- import { c as createLogger, v as version, f as name } from './shared/univo.mlthZw0m.mjs';
8
+ import { c as createLogger, v as version, f as name } from './shared/univo.CUNaTwXY.mjs';
9
9
 
10
10
  const log = createLogger({ quiet: false });
11
11
  const dev = defineCommand({
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Action, B as Block, E as Event, F as Filter, H as Head, c as Indexer, M as Metadata, e as Result, b as defineAction, a as defineEvent, d as defineIndexer } from './shared/univo.DYd1g40o.mjs';
1
+ export { A as Action, B as Block, E as Event, F as Filter, H as Head, e as Indexer, f as PrivateMetadata, P as PublicMetadata, g as Result, c as defineAction, a as defineEvent, d as defineIndexer } from './shared/univo.Ckj3I8tQ.mjs';
2
2
  import 'viem';
3
3
  import './metadata.mjs';
4
4
  import './metadata/adapters.mjs';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Action, B as Block, E as Event, F as Filter, H as Head, c as Indexer, M as Metadata, e as Result, b as defineAction, a as defineEvent, d as defineIndexer } from './shared/univo.CEA4vY0E.js';
1
+ export { A as Action, B as Block, E as Event, F as Filter, H as Head, e as Indexer, f as PrivateMetadata, P as PublicMetadata, g as Result, c as defineAction, a as defineEvent, d as defineIndexer } from './shared/univo.7S1OTdpc.js';
2
2
  import 'viem';
3
3
  import './metadata.js';
4
4
  import './metadata/adapters.js';
package/dist/index.mjs CHANGED
@@ -1,50 +1,111 @@
1
- import { hexToNumber, numberToHex, hexToBytes, keccak256, toRlp, hexToBigInt, formatTransaction, serializeTransaction, numberToBytes, isHex, concatBytes } from 'viem';
1
+ import { hexToNumber, numberToHex, hexToBytes, keccak256, toRlp, hexToBigInt, numberToBytes, isHex, concatBytes, concatHex, formatTransaction, serializeTransaction } from 'viem';
2
2
  import { local } from './transport.mjs';
3
- import { c as createLogger, r as retry, v as version, n as normalizeHex, d as decompress, i as isHexEqual, a as compress, b as iife, e as decoder } from './shared/univo.mlthZw0m.mjs';
3
+ import { c as createLogger, r as retry, v as version, n as normalizeHex, d as decompress, i as isHexEqual, a as compress, b as iife, e as decoder } from './shared/univo.CUNaTwXY.mjs';
4
4
  import { AdapterError } from './metadata/adapters.mjs';
5
5
  import { c as createException, a as catchException } from './shared/univo.C0flyVee.mjs';
6
6
  import 'ws';
7
7
  import 'partysocket';
8
8
 
9
9
  function matchFilter(block, filter) {
10
- if (!chainValid(block, filter)) return false;
11
- if (!toBlockValid(block, filter)) return false;
12
- if (!fromBlockValid(block, filter)) return false;
13
- if (!includesLogEvent(block, filter)) return false;
14
- if (!includesLogAddress(block, filter)) return false;
15
- return true;
16
- }
17
- const chainValid = (block, filter) => {
18
- if (hexToNumber(block.eth_chainId) === filter.chain) return true;
19
- return false;
20
- };
21
- const fromBlockValid = (block, filter) => {
22
- if (hexToNumber(block.eth_getBlockByNumber.number) >= filter.fromBlock) return true;
23
- return false;
24
- };
25
- const toBlockValid = (block, filter) => {
26
- if (filter.toBlock === void 0) return true;
27
- if (hexToNumber(block.eth_getBlockByNumber.number) <= filter.toBlock) return true;
28
- return false;
29
- };
30
- const includesLogAddress = (block, filter) => {
31
- if (filter.address === void 0) return true;
32
- for (const receipt of block.eth_getBlockReceipts) {
33
- for (const log of receipt.logs) {
34
- if (isHexEqual(log.address, filter.address)) return true;
10
+ if (hexToNumber(block.eth_chainId) !== filter.chain) {
11
+ return false;
12
+ }
13
+ if (hexToNumber(block.eth_getBlockByNumber.number) < filter.fromBlock) {
14
+ return false;
15
+ }
16
+ if (typeof filter.toBlock === "number" && hexToNumber(block.eth_getBlockByNumber.number) > filter.toBlock) {
17
+ return false;
18
+ }
19
+ if (filter.address && filter.event && filter.function) {
20
+ const txs = [];
21
+ for (const tx of block.eth_getBlockByNumber.transactions) {
22
+ if (tx.to !== null && isHexEqual(tx.to, filter.address)) {
23
+ if (isHexEqual(tx.input.slice(0, 10), filter.function)) {
24
+ txs.push(tx.transactionIndex);
25
+ }
26
+ }
27
+ }
28
+ for (const receipt of block.eth_getBlockReceipts) {
29
+ for (const log of receipt.logs) {
30
+ if (log.topics[0] !== void 0 && isHexEqual(log.topics[0], filter.event)) {
31
+ if (isHexEqual(log.address, filter.address)) {
32
+ if (txs.some((tx) => isHexEqual(tx, log.transactionIndex))) {
33
+ return true;
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ return false;
40
+ }
41
+ if (filter.address && filter.event && filter.function === void 0) {
42
+ for (const receipt of block.eth_getBlockReceipts) {
43
+ for (const log of receipt.logs) {
44
+ if (log.topics[0] !== void 0 && isHexEqual(log.topics[0], filter.event)) {
45
+ if (isHexEqual(log.address, filter.address)) {
46
+ return true;
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return false;
52
+ }
53
+ if (filter.address && filter.event === void 0 && filter.function) {
54
+ for (const tx of block.eth_getBlockByNumber.transactions) {
55
+ if (tx.to !== null && isHexEqual(tx.to, filter.address)) {
56
+ if (isHexEqual(tx.input.slice(0, 10), filter.function)) {
57
+ return true;
58
+ }
59
+ }
60
+ }
61
+ return false;
62
+ }
63
+ if (filter.address === void 0 && filter.event && filter.function) {
64
+ const txs = [];
65
+ for (const tx of block.eth_getBlockByNumber.transactions) {
66
+ if (tx.to !== null && isHexEqual(tx.input.slice(0, 10), filter.function)) {
67
+ txs.push(tx.transactionIndex);
68
+ }
69
+ }
70
+ for (const receipt of block.eth_getBlockReceipts) {
71
+ for (const log of receipt.logs) {
72
+ if (log.topics[0] !== void 0 && isHexEqual(log.topics[0], filter.event)) {
73
+ if (txs.some((tx) => isHexEqual(tx, log.transactionIndex))) {
74
+ return true;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ return false;
80
+ }
81
+ if (filter.address === void 0 && filter.event && filter.function === void 0) {
82
+ for (const receipt of block.eth_getBlockReceipts) {
83
+ for (const log of receipt.logs) {
84
+ if (log.topics[0] !== void 0 && isHexEqual(log.topics[0], filter.event)) {
85
+ return true;
86
+ }
87
+ }
35
88
  }
89
+ return false;
36
90
  }
37
- return false;
38
- };
39
- const includesLogEvent = (block, filter) => {
40
- if (filter.event === void 0) return true;
41
- for (const receipt of block.eth_getBlockReceipts) {
42
- for (const log of receipt.logs) {
43
- if (log.topics[0] === filter.event) return true;
91
+ if (filter.address === void 0 && filter.event === void 0 && filter.function) {
92
+ for (const tx of block.eth_getBlockByNumber.transactions) {
93
+ if (tx.to !== null && isHexEqual(tx.input.slice(0, 10), filter.function)) {
94
+ return true;
95
+ }
44
96
  }
97
+ return false;
45
98
  }
46
- return false;
47
- };
99
+ if (filter.address && filter.event === void 0 && filter.function === void 0) {
100
+ for (const tx of block.eth_getBlockByNumber.transactions) {
101
+ if (isHexEqual(tx.from, filter.address) || tx.to !== null && isHexEqual(tx.to, filter.address)) {
102
+ return true;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+ return true;
108
+ }
48
109
  function defineEvent(event) {
49
110
  return event;
50
111
  }
@@ -52,7 +113,7 @@ function defineAction(action) {
52
113
  return action;
53
114
  }
54
115
  function defineIndexer(opts) {
55
- const log = createLogger({ quiet: opts.quiet ?? false, prefix: "[indexer]" });
116
+ const log = createLogger({ quiet: opts.quiet, prefix: "[indexer]" });
56
117
  const allEvents = [...opts.events];
57
118
  const eventsGroupedByStorageMap = /* @__PURE__ */ new Map();
58
119
  for (const event of allEvents) {
@@ -74,6 +135,43 @@ function defineIndexer(opts) {
74
135
  }
75
136
  actionIds.add(action.id);
76
137
  }
138
+ const public_getMetadata = async () => {
139
+ return {
140
+ chains: Array.from(
141
+ new Set(
142
+ allEvents.flatMap((event) => {
143
+ return event.filters.flatMap((filter) => {
144
+ return numberToHex(filter.chain);
145
+ });
146
+ })
147
+ )
148
+ )
149
+ };
150
+ };
151
+ const public_getFinalizedHeight = async (chain) => {
152
+ const manifest = await getOrInitManifest(chain);
153
+ return manifest.finalized_block_height;
154
+ };
155
+ async function getOrInitManifest(chain) {
156
+ const path = `manifest/v1/${normalizeHex(chain)}`;
157
+ const manifestRes = await opts.metadataStorage.adapter.get(path);
158
+ let manifest;
159
+ if (manifestRes === null) {
160
+ const block = await getBlockFromChain({ chain, number: "finalized" });
161
+ const chainFinalizedHeight = hexToNumber(block.eth_getBlockByNumber.number);
162
+ const newManifest = {
163
+ finalized_block_height: chainFinalizedHeight,
164
+ finalized_block_hash: block.eth_getBlockByNumber.hash,
165
+ next_finalized_height: chainFinalizedHeight,
166
+ updated_at: Date.now()
167
+ };
168
+ await opts.metadataStorage.adapter.put(path, JSON.stringify(newManifest), { ifNoneMatch: "*" });
169
+ manifest = newManifest;
170
+ } else {
171
+ manifest = JSON.parse(decoder.decode(manifestRes.body));
172
+ }
173
+ return manifest;
174
+ }
77
175
  async function getBlockFromChain(head) {
78
176
  return await retry(() => retry_getBlockFromChain(head), 2);
79
177
  }
@@ -261,6 +359,45 @@ function defineIndexer(opts) {
261
359
  const type = hexToBigInt(receipt.type);
262
360
  return type === 0n ? encoded : concatBytes([Uint8Array.of(Number(type)), encoded]);
263
361
  }
362
+ function serializeTransaction$1(tx) {
363
+ if (tx.type === "0x4") {
364
+ return concatHex([
365
+ "0x04",
366
+ toRlp([
367
+ quantityToBytes(tx.chainId),
368
+ quantityToBytes(tx.nonce),
369
+ quantityToBytes(tx.maxPriorityFeePerGas),
370
+ quantityToBytes(tx.maxFeePerGas),
371
+ quantityToBytes(tx.gas),
372
+ hexToBytes(tx.to),
373
+ quantityToBytes(tx.value),
374
+ hexToBytes(tx.input),
375
+ tx.accessList.map(({ address, storageKeys }) => [hexToBytes(address), storageKeys.map((key) => hexToBytes(key))]),
376
+ (tx.authorizationList ?? []).map((authorization) => [
377
+ quantityToBytes(authorization.chainId),
378
+ hexToBytes(authorization.address),
379
+ quantityToBytes(authorization.nonce),
380
+ quantityToBytes(authorization.yParity),
381
+ quantityToBytes(authorization.r),
382
+ quantityToBytes(authorization.s)
383
+ ]),
384
+ quantityToBytes(tx.yParity ?? tx.v),
385
+ quantityToBytes(tx.r),
386
+ quantityToBytes(tx.s)
387
+ ])
388
+ ]);
389
+ }
390
+ const { input, ...formatted } = formatTransaction(tx);
391
+ if (formatted.type === "legacy" && (formatted.v === 27n || formatted.v === 28n)) {
392
+ formatted.chainId = void 0;
393
+ }
394
+ const signature = formatted.type === "legacy" ? { r: formatted.r, s: formatted.s, v: formatted.v } : { r: formatted.r, s: formatted.s, yParity: formatted.yParity };
395
+ return serializeTransaction(
396
+ { ...formatted, data: input },
397
+ //
398
+ signature
399
+ );
400
+ }
264
401
  const SUPPORTED_TRANSACTION_TYPES = /* @__PURE__ */ new Set([0n, 1n, 2n, 3n, 4n]);
265
402
  function verifyTransactionsRoot(block) {
266
403
  const unsupportedTxs = block.eth_getBlockByNumber.transactions.filter((tx) => {
@@ -273,16 +410,7 @@ function defineIndexer(opts) {
273
410
  return log.warn("Unable to verify block `transactionsRoot` because of unsupported tx type");
274
411
  }
275
412
  const transactions = block.eth_getBlockByNumber.transactions.map((tx) => {
276
- const { input, ...formatted } = formatTransaction(tx);
277
- if (formatted.type === "legacy" && (formatted.v === 27n || formatted.v === 28n)) {
278
- formatted.chainId = void 0;
279
- }
280
- const signature = formatted.type === "legacy" ? { r: formatted.r, s: formatted.s, v: formatted.v } : { r: formatted.r, s: formatted.s, yParity: formatted.yParity };
281
- const serialized = serializeTransaction(
282
- { ...formatted, data: input },
283
- //
284
- signature
285
- );
413
+ const serialized = serializeTransaction$1(tx);
286
414
  if (!isHexEqual(tx.hash, keccak256(serialized))) {
287
415
  throw new Error(`Transaction ${tx.hash} failed serialization check`);
288
416
  }
@@ -334,30 +462,6 @@ function defineIndexer(opts) {
334
462
  throw new Error("Block returned inconsistent gas used");
335
463
  }
336
464
  }
337
- const public_getFinalizedHeight = async (chain) => {
338
- const manifest = await getOrInitManifest(chain);
339
- return manifest.finalized_block_height;
340
- };
341
- async function getOrInitManifest(chain) {
342
- const path = `manifest/v1/${normalizeHex(chain)}`;
343
- const manifestRes = await opts.metadataStorage.adapter.get(path);
344
- let manifest;
345
- if (manifestRes === null) {
346
- const block = await getBlockFromChain({ chain, number: "finalized" });
347
- const chainFinalizedHeight = hexToNumber(block.eth_getBlockByNumber.number);
348
- const newManifest = {
349
- finalized_block_height: chainFinalizedHeight,
350
- finalized_block_hash: block.eth_getBlockByNumber.hash,
351
- next_finalized_height: chainFinalizedHeight,
352
- updated_at: Date.now()
353
- };
354
- await opts.metadataStorage.adapter.put(path, JSON.stringify(newManifest), { ifNoneMatch: "*" });
355
- manifest = newManifest;
356
- } else {
357
- manifest = JSON.parse(decoder.decode(manifestRes.body));
358
- }
359
- return manifest;
360
- }
361
465
  const public_writeUnfinalizedHead = async (head) => {
362
466
  log.debug("Received unfinalized head...");
363
467
  const blocksStart = Date.now();
@@ -909,23 +1013,22 @@ function defineIndexer(opts) {
909
1013
  const private_getMetadata = async () => {
910
1014
  return {
911
1015
  version,
912
- language: "javascript"
1016
+ language: "javascript",
1017
+ events: allEvents.map((event) => {
1018
+ const filters = event.filters.map((filter) => {
1019
+ return {
1020
+ chain: filter.chain,
1021
+ event: filter.event,
1022
+ address: filter.address,
1023
+ to_block: filter.toBlock,
1024
+ function: filter.function,
1025
+ from_block: filter.fromBlock
1026
+ };
1027
+ });
1028
+ return { id: event.id, filters };
1029
+ })
913
1030
  };
914
1031
  };
915
- const private_getEvents = async () => {
916
- return allEvents.map((event) => {
917
- const filters = event.filters.map((filter) => {
918
- return {
919
- chain: filter.chain,
920
- event: filter.event,
921
- address: filter.address,
922
- to_block: filter.toBlock,
923
- from_block: filter.fromBlock
924
- };
925
- });
926
- return { id: event.id, filters };
927
- });
928
- };
929
1032
  const ignored = [
930
1033
  "toJSON",
931
1034
  "toString",
@@ -1177,12 +1280,12 @@ function defineIndexer(opts) {
1177
1280
  const rpc = {
1178
1281
  request: {
1179
1282
  public_finalize,
1283
+ public_getMetadata,
1180
1284
  public_getFinalizedHeight,
1181
1285
  public_writeFinalizedHead,
1182
1286
  public_writeFinalizedHeight,
1183
1287
  public_writeUnfinalizedHead,
1184
1288
  public_deleteReorganisedHead,
1185
- private_getEvents,
1186
1289
  private_getMetadata,
1187
1290
  private_writeEvents,
1188
1291
  private_writeEventsAndGetKeys
package/dist/proxy.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { T as Transport, I as IndexerRpc } from './shared/univo.DYd1g40o.mjs';
1
+ import { T as Transport, I as IndexerRpc } from './shared/univo.Ckj3I8tQ.mjs';
2
2
  import 'viem';
3
3
  import './metadata.mjs';
4
4
  import './metadata/adapters.mjs';
package/dist/proxy.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { T as Transport, I as IndexerRpc } from './shared/univo.CEA4vY0E.js';
1
+ import { T as Transport, I as IndexerRpc } from './shared/univo.7S1OTdpc.js';
2
2
  import 'viem';
3
3
  import './metadata.js';
4
4
  import './metadata/adapters.js';
package/dist/proxy.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { g as getException } from './shared/univo.C0flyVee.mjs';
2
- import { c as createLogger, d as decompress, e as decoder } from './shared/univo.mlthZw0m.mjs';
2
+ import { c as createLogger, d as decompress, e as decoder } from './shared/univo.CUNaTwXY.mjs';
3
3
 
4
4
  function http(opts) {
5
- const log = createLogger({ quiet: opts.quiet ?? false, prefix: "[proxy]" });
5
+ const log = createLogger({ quiet: opts.quiet, prefix: "[proxy]" });
6
6
  return async function proxy(req) {
7
7
  let body_buffer;
8
8
  try {
@@ -1,4 +1,4 @@
1
- import { T as Transport, R as Rpc, I as IndexerRpc } from './shared/univo.DYd1g40o.mjs';
1
+ import { T as Transport, R as Rpc, I as IndexerRpc } from './shared/univo.Ckj3I8tQ.mjs';
2
2
  import 'viem';
3
3
  import './metadata.mjs';
4
4
  import './metadata/adapters.mjs';
@@ -14,9 +14,9 @@ type RealtimeOptions = {
14
14
  /**
15
15
  * Connection to a blockchain node.
16
16
  *
17
- * Must use the `wss` transport protocol from `univo/transport`.
17
+ * Must use the `wss` or `browser` transport protocol from `univo/transport`.
18
18
  */
19
- node: Transport<Rpc, "wss">;
19
+ node: Transport<Rpc, "wss" | "browser">;
20
20
  /**
21
21
  * Connection to a univo indexer.
22
22
  *
@@ -25,6 +25,6 @@ type RealtimeOptions = {
25
25
  */
26
26
  indexer: Transport<IndexerRpc, "http" | "local">;
27
27
  };
28
- declare function realtime(opts: RealtimeOptions): void;
28
+ declare function realtime(realtime: RealtimeOptions): void;
29
29
 
30
30
  export { realtime };
@@ -1,4 +1,4 @@
1
- import { T as Transport, R as Rpc, I as IndexerRpc } from './shared/univo.CEA4vY0E.js';
1
+ import { T as Transport, R as Rpc, I as IndexerRpc } from './shared/univo.7S1OTdpc.js';
2
2
  import 'viem';
3
3
  import './metadata.js';
4
4
  import './metadata/adapters.js';
@@ -14,9 +14,9 @@ type RealtimeOptions = {
14
14
  /**
15
15
  * Connection to a blockchain node.
16
16
  *
17
- * Must use the `wss` transport protocol from `univo/transport`.
17
+ * Must use the `wss` or `browser` transport protocol from `univo/transport`.
18
18
  */
19
- node: Transport<Rpc, "wss">;
19
+ node: Transport<Rpc, "wss" | "browser">;
20
20
  /**
21
21
  * Connection to a univo indexer.
22
22
  *
@@ -25,6 +25,6 @@ type RealtimeOptions = {
25
25
  */
26
26
  indexer: Transport<IndexerRpc, "http" | "local">;
27
27
  };
28
- declare function realtime(opts: RealtimeOptions): void;
28
+ declare function realtime(realtime: RealtimeOptions): void;
29
29
 
30
30
  export { realtime };