@notuslabs/yail 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +19 -4
  2. package/dist/cache/cached.d.ts.map +1 -1
  3. package/dist/cache/cached.js +5 -3
  4. package/dist/cache/cached.js.map +1 -1
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +7 -4
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/config/create-config.d.ts +1 -1
  9. package/dist/config/create-config.d.ts.map +1 -1
  10. package/dist/config/create-config.js +2 -2
  11. package/dist/config/create-config.js.map +1 -1
  12. package/dist/config/types.d.ts +5 -5
  13. package/dist/config/types.d.ts.map +1 -1
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/indexer/context.d.ts +4 -3
  19. package/dist/indexer/context.d.ts.map +1 -1
  20. package/dist/indexer/context.js.map +1 -1
  21. package/dist/indexer/events.d.ts +26 -2
  22. package/dist/indexer/events.d.ts.map +1 -1
  23. package/dist/indexer/events.js +16 -0
  24. package/dist/indexer/events.js.map +1 -1
  25. package/dist/indexer/indexer.d.ts +2 -12
  26. package/dist/indexer/indexer.d.ts.map +1 -1
  27. package/dist/indexer/indexer.js +20 -22
  28. package/dist/indexer/indexer.js.map +1 -1
  29. package/dist/indexer/plan.d.ts +6 -7
  30. package/dist/indexer/plan.d.ts.map +1 -1
  31. package/dist/indexer/plan.js +13 -36
  32. package/dist/indexer/plan.js.map +1 -1
  33. package/dist/indexer/runtime.d.ts +4 -6
  34. package/dist/indexer/runtime.d.ts.map +1 -1
  35. package/dist/indexer/runtime.js +57 -40
  36. package/dist/indexer/runtime.js.map +1 -1
  37. package/dist/sources/cached.d.ts.map +1 -1
  38. package/dist/sources/cached.js +37 -21
  39. package/dist/sources/cached.js.map +1 -1
  40. package/dist/sources/esplora.d.ts.map +1 -1
  41. package/dist/sources/esplora.js +8 -37
  42. package/dist/sources/esplora.js.map +1 -1
  43. package/dist/sources/fixture.d.ts +23 -2
  44. package/dist/sources/fixture.d.ts.map +1 -1
  45. package/dist/sources/fixture.js +34 -0
  46. package/dist/sources/fixture.js.map +1 -1
  47. package/dist/sources/hypersync.d.ts +10 -1
  48. package/dist/sources/hypersync.d.ts.map +1 -1
  49. package/dist/sources/hypersync.js +6 -0
  50. package/dist/sources/hypersync.js.map +1 -1
  51. package/dist/sources/index.d.ts +5 -4
  52. package/dist/sources/index.d.ts.map +1 -1
  53. package/dist/sources/index.js +2 -1
  54. package/dist/sources/index.js.map +1 -1
  55. package/dist/sources/rpc.d.ts +7 -1
  56. package/dist/sources/rpc.d.ts.map +1 -1
  57. package/dist/sources/rpc.js +7 -16
  58. package/dist/sources/rpc.js.map +1 -1
  59. package/dist/sources/solana/hypersync.d.ts +25 -0
  60. package/dist/sources/solana/hypersync.d.ts.map +1 -0
  61. package/dist/sources/solana/hypersync.js +117 -0
  62. package/dist/sources/solana/hypersync.js.map +1 -0
  63. package/dist/sources/solana/rpc.d.ts +25 -0
  64. package/dist/sources/solana/rpc.d.ts.map +1 -0
  65. package/dist/sources/solana/rpc.js +134 -0
  66. package/dist/sources/solana/rpc.js.map +1 -0
  67. package/dist/sources/solana/shared.d.ts +12 -0
  68. package/dist/sources/solana/shared.d.ts.map +1 -0
  69. package/dist/sources/solana/shared.js +30 -0
  70. package/dist/sources/solana/shared.js.map +1 -0
  71. package/dist/sources/types.d.ts +69 -11
  72. package/dist/sources/types.d.ts.map +1 -1
  73. package/dist/sources/types.js +2 -2
  74. package/dist/sources/types.js.map +1 -1
  75. package/dist/sources/union.d.ts +12 -0
  76. package/dist/sources/union.d.ts.map +1 -0
  77. package/dist/sources/union.js +65 -0
  78. package/dist/sources/union.js.map +1 -0
  79. package/dist/testing/index.d.ts +2 -2
  80. package/dist/testing/index.d.ts.map +1 -1
  81. package/dist/testing/index.js +1 -1
  82. package/dist/testing/index.js.map +1 -1
  83. package/dist/util.d.ts +9 -0
  84. package/dist/util.d.ts.map +1 -1
  85. package/dist/util.js +58 -0
  86. package/dist/util.js.map +1 -1
  87. package/package.json +3 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/sources/solana/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAIvI,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,oHAAoH;IACpH,GAAG,EAAE,MAAM,CAAC;IACZ,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gCAAgC;IAChC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,qEAAqE;AACrE,eAAO,MAAM,cAAc,UAAiG,CAAC;AA0B7H;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAyFjE"}
@@ -0,0 +1,134 @@
1
+ import { mapLimit, request } from "../../util.js";
2
+ import { finishBatch, solanaBalance, walletOf } from "./shared.js";
3
+ /** Programs whose accounts hold tokens: SPL Token and Token-2022. */
4
+ export const TOKEN_PROGRAMS = ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"];
5
+ /**
6
+ * Solana source over plain JSON-RPC, address by address: `getSignaturesForAddress` for each wallet and each token
7
+ * account it owns, then `getTransaction` for each signature. Cost grows with the wallets' transactions, not with
8
+ * the slot range, so it suits old history of a few wallets: put it after `hypersync({ kind: "solana" })` in `union()`.
9
+ *
10
+ * Transfers into a token account do not name its wallet, so the token accounts' own signatures are read too. Open
11
+ * ones come from `getTokenAccountsByOwner`. A closed one shows up in the transaction that closed it, which needs the
12
+ * owner's signature: the wallet's transactions from the range's start up to the head name every account that existed
13
+ * in the range. Those past the range are read only for that, and remembered.
14
+ */
15
+ export function solanaRpc(options) {
16
+ const doFetch = options.fetch ?? fetch;
17
+ const concurrency = options.concurrency ?? 4;
18
+ let id = 0;
19
+ /** Token accounts (account, owner) seen in each transaction read so far, for closed-account discovery. */
20
+ const tokenAccountsIn = new Map();
21
+ async function call(method, params, signal) {
22
+ const init = { method: "POST", headers: { "Content-Type": "application/json", ...options.headers }, body: JSON.stringify({ jsonrpc: "2.0", id: ++id, method, params }), signal };
23
+ const text = await request(doFetch, options.url, init);
24
+ // Lamports can pass 2^53: keep such numbers exact.
25
+ const res = JSON.parse(text, (_key, value, context) => {
26
+ if (typeof value === "number" && !Number.isSafeInteger(value) && context?.source && /^\d+$/.test(context.source))
27
+ return BigInt(context.source);
28
+ return value;
29
+ });
30
+ if (res.error)
31
+ throw new Error(`rpc(${new URL(options.url).host}) ${method}: ${res.error.code} ${res.error.message}`);
32
+ return res.result;
33
+ }
34
+ /** Signatures mentioning `account` in [from, to), newest first in pages of 1000. */
35
+ async function signatures(account, from, to, signal) {
36
+ const out = [];
37
+ let before;
38
+ for (;;) {
39
+ const page = await call("getSignaturesForAddress", [account, { limit: 1000, before, commitment: "confirmed" }], signal);
40
+ for (const s of page)
41
+ if (s.slot >= from && s.slot < to)
42
+ out.push({ signature: s.signature, slot: s.slot });
43
+ if (page.length < 1000 || page.at(-1).slot < from)
44
+ return out;
45
+ before = page.at(-1).signature;
46
+ }
47
+ }
48
+ async function getTransaction(signature, signal) {
49
+ const raw = await call("getTransaction", [signature, { encoding: "json", maxSupportedTransactionVersion: 1, commitment: "confirmed" }], signal);
50
+ const keys = accountKeys(raw);
51
+ tokenAccountsIn.set(signature, [...(raw.meta.preTokenBalances ?? []), ...(raw.meta.postTokenBalances ?? [])].filter((t) => t.owner).map((t) => [keys[t.accountIndex], t.owner]));
52
+ return raw;
53
+ }
54
+ /** Fill `transactionIndex` where the provider left it out: one `getBlock` (signatures only) per such slot. */
55
+ async function orderInSlots(raws, signal) {
56
+ const slots = [...new Set(raws.filter((r) => r.transactionIndex === undefined).map((r) => r.slot))];
57
+ const blocks = await mapLimit(slots, concurrency, (slot) => call("getBlock", [slot, { transactionDetails: "signatures", rewards: false, maxSupportedTransactionVersion: 1, commitment: "confirmed" }], signal));
58
+ const index = new Map(blocks.flatMap((b) => b.signatures.map((sig, i) => [sig, i])));
59
+ for (const raw of raws)
60
+ raw.transactionIndex ??= index.get(raw.transaction.signatures[0]);
61
+ }
62
+ async function tokenAccounts(owner, signal) {
63
+ const lists = await Promise.all(TOKEN_PROGRAMS.map((programId) => call("getTokenAccountsByOwner", [owner, { programId }, { encoding: "base64", dataSlice: { offset: 0, length: 0 }, commitment: "confirmed" }], signal)));
64
+ return lists.flatMap((l) => l.value.map((a) => a.pubkey));
65
+ }
66
+ return {
67
+ kind: "solana",
68
+ name: `rpc(${new URL(options.url).host})`,
69
+ async getHeight() {
70
+ return call("getSlot", [{ commitment: "confirmed" }]);
71
+ },
72
+ async *fetch(query, fetchOptions) {
73
+ const signal = fetchOptions?.signal;
74
+ const wallets = new Set(query.addresses);
75
+ const inRange = (slot) => slot >= query.fromBlock && slot < query.toBlock;
76
+ const txs = new Map();
77
+ /** Token account -> owning wallet. */
78
+ const owners = new Map();
79
+ for (const [wallet, accounts] of await mapLimit([...wallets], concurrency, async (w) => [w, await tokenAccounts(w, signal)])) {
80
+ for (const a of accounts)
81
+ owners.set(a, wallet);
82
+ }
83
+ const own = unique((await mapLimit([...wallets], concurrency, (w) => signatures(w, query.fromBlock, Infinity, signal))).flat());
84
+ await mapLimit(own, concurrency, async ({ signature, slot }) => {
85
+ if (!inRange(slot) && tokenAccountsIn.has(signature))
86
+ return;
87
+ const raw = await getTransaction(signature, signal);
88
+ if (inRange(slot))
89
+ txs.set(signature, raw);
90
+ });
91
+ for (const { signature } of own) {
92
+ for (const [account, owner] of tokenAccountsIn.get(signature) ?? [])
93
+ if (wallets.has(owner))
94
+ owners.set(account, owner);
95
+ }
96
+ const received = unique((await mapLimit([...owners.keys()], concurrency, (a) => signatures(a, query.fromBlock, query.toBlock, signal))).flat());
97
+ const fresh = received.filter((s) => !txs.has(s.signature));
98
+ for (const raw of await mapLimit(fresh, concurrency, (s) => getTransaction(s.signature, signal)))
99
+ txs.set(raw.transaction.signatures[0], raw);
100
+ await orderInSlots([...txs.values()], signal);
101
+ yield finishBatch(toBatch([...txs.values()], wallets, owners, query));
102
+ },
103
+ };
104
+ }
105
+ function unique(list) {
106
+ return [...new Map(list.map((s) => [s.signature, s])).values()];
107
+ }
108
+ function accountKeys(raw) {
109
+ const loaded = raw.meta.loadedAddresses;
110
+ return [...raw.transaction.message.accountKeys, ...(loaded?.writable ?? []), ...(loaded?.readonly ?? [])];
111
+ }
112
+ function toBatch(raws, wallets, owners, query) {
113
+ const blocks = new Map();
114
+ const transactions = [];
115
+ const balances = [];
116
+ for (const raw of raws) {
117
+ const keys = accountKeys(raw);
118
+ const tx = { signature: raw.transaction.signatures[0], slot: raw.slot, transactionIndex: raw.transactionIndex, feePayer: keys[0], fee: BigInt(raw.meta.fee), success: raw.meta.err === null };
119
+ transactions.push(tx);
120
+ blocks.set(raw.slot, { slot: raw.slot, time: raw.blockTime ?? 0 });
121
+ const pre = new Map((raw.meta.preTokenBalances ?? []).map((t) => [t.accountIndex, t]));
122
+ const post = new Map((raw.meta.postTokenBalances ?? []).map((t) => [t.accountIndex, t]));
123
+ keys.forEach((account, i) => {
124
+ const token = post.get(i) ?? pre.get(i);
125
+ const owner = token?.owner ?? owners.get(account) ?? "";
126
+ const tokens = token && { mint: token.mint, owner, decimals: token.uiTokenAmount.decimals, pre: BigInt(pre.get(i)?.uiTokenAmount.amount ?? 0), post: BigInt(post.get(i)?.uiTokenAmount.amount ?? 0) };
127
+ const row = solanaBalance({ signature: tx.signature, slot: tx.slot, transactionIndex: tx.transactionIndex, account }, BigInt(raw.meta.preBalances[i]), BigInt(raw.meta.postBalances[i]), tokens);
128
+ if (wallets.has(walletOf(row)))
129
+ balances.push(row);
130
+ });
131
+ }
132
+ return { fromBlock: query.fromBlock, nextBlock: query.toBlock, blocks: [...blocks.values()], transactions, balances };
133
+ }
134
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../../src/sources/solana/rpc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { SolanaBalance, SolanaBatch } from "../types.js";
2
+ /** The wallet a balance row belongs to: a token account's owner, otherwise the account itself. */
3
+ export declare function walletOf(b: Pick<SolanaBalance, "account" | "token">): string;
4
+ /** A balance row, with `lamports` only when they changed: every Solana source reports the same rows. */
5
+ export declare function solanaBalance(at: Pick<SolanaBalance, "signature" | "slot" | "transactionIndex" | "account">, preLamports: bigint, postLamports: bigint, token?: SolanaBalance["token"]): SolanaBalance;
6
+ /**
7
+ * Keep the rows where something changed and the transactions and blocks they belong to, in chain order. Sources
8
+ * disagree on unchanged accounts (RPC lists every account a transaction touches, HyperSync only some), so they
9
+ * are dropped and every source answers the same.
10
+ */
11
+ export declare function finishBatch(batch: SolanaBatch): SolanaBatch;
12
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/sources/solana/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAkC,MAAM,aAAa,CAAC;AAE9F,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,MAAM,CAG5E;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,aAAa,CAKtM;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAQ3D"}
@@ -0,0 +1,30 @@
1
+ /** The wallet a balance row belongs to: a token account's owner, otherwise the account itself. */
2
+ export function walletOf(b) {
3
+ if (b.token)
4
+ return b.token.owner;
5
+ return b.account;
6
+ }
7
+ /** A balance row, with `lamports` only when they changed: every Solana source reports the same rows. */
8
+ export function solanaBalance(at, preLamports, postLamports, token) {
9
+ const balance = { ...at };
10
+ if (preLamports !== postLamports)
11
+ balance.lamports = { pre: preLamports, post: postLamports };
12
+ if (token)
13
+ balance.token = token;
14
+ return balance;
15
+ }
16
+ /**
17
+ * Keep the rows where something changed and the transactions and blocks they belong to, in chain order. Sources
18
+ * disagree on unchanged accounts (RPC lists every account a transaction touches, HyperSync only some), so they
19
+ * are dropped and every source answers the same.
20
+ */
21
+ export function finishBatch(batch) {
22
+ const order = (a, b) => a.slot - b.slot || a.transactionIndex - b.transactionIndex;
23
+ batch.balances = batch.balances.filter((b) => b.lamports || (b.token && b.token.pre !== b.token.post)).sort(order);
24
+ const signatures = new Set(batch.balances.map((b) => b.signature));
25
+ batch.transactions = batch.transactions.filter((t) => signatures.has(t.signature)).sort(order);
26
+ const slots = new Set(batch.transactions.map((t) => t.slot));
27
+ batch.blocks = batch.blocks.filter((b) => slots.has(b.slot)).sort((a, b) => a.slot - b.slot);
28
+ return batch;
29
+ }
30
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/sources/solana/shared.ts"],"names":[],"mappings":"AAEA,kGAAkG;AAClG,MAAM,UAAU,QAAQ,CAAC,CAA2C;IAClE,IAAI,CAAC,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,OAAO,CAAC,CAAC,OAAO,CAAC;AACnB,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,aAAa,CAAC,EAA8E,EAAE,WAAmB,EAAE,YAAoB,EAAE,KAA8B;IACrL,MAAM,OAAO,GAAkB,EAAE,GAAG,EAAE,EAAE,CAAC;IACzC,IAAI,WAAW,KAAK,YAAY;QAAE,OAAO,CAAC,QAAQ,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAC9F,IAAI,KAAK;QAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,MAAM,KAAK,GAAG,CAAC,CAA6C,EAAE,CAA6C,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;IAC3K,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACnE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAoB,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1G,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,12 +1,21 @@
1
1
  /**
2
2
  * Source abstraction. Every data provider (HyperSync, JSON-RPC, the cache
3
- * wrapper, Esplora for Bitcoin, recorded fixtures) implements the same
4
- * shape: `getHeight()` and `fetch(query)` yielding ordered, contiguous
3
+ * wrapper, Esplora for Bitcoin, Solana RPC, recorded fixtures) implements the
4
+ * same shape: `getHeight()` and `fetch(query)` yielding ordered, contiguous
5
5
  * batches of blocks/transactions/logs for a block range.
6
6
  */
7
7
  export interface FetchOptions {
8
8
  signal?: AbortSignal;
9
9
  }
10
+ interface SourceBase {
11
+ readonly name: string;
12
+ getHeight(): Promise<number>;
13
+ /**
14
+ * First block the source holds data for. Absent means the whole chain. `union()` sends nothing below it, so a
15
+ * source with partial history (Solana HyperSync keeps only recent slots) never gets a range it cannot serve.
16
+ */
17
+ firstBlock?(): Promise<number>;
18
+ }
10
19
  export interface RangeQuery {
11
20
  fromBlock: number;
12
21
  /** Exclusive. */
@@ -113,10 +122,8 @@ export interface EvmBatch extends RangeBatch {
113
122
  rollbackGuard?: RollbackGuard;
114
123
  archiveHeight?: number;
115
124
  }
116
- export interface EvmSource {
125
+ export interface EvmSource extends SourceBase {
117
126
  readonly kind: "evm";
118
- readonly name: string;
119
- getHeight(): Promise<number>;
120
127
  fetch(query: EvmQuery, options?: FetchOptions): AsyncIterable<EvmBatch>;
121
128
  /** Optional: block header lookup (used for reorg checks and `startBlock: "latest"`). */
122
129
  getBlock?(number: number): Promise<EvmBlock | null>;
@@ -151,18 +158,69 @@ export interface BitcoinTransaction {
151
158
  export interface BitcoinBatch extends RangeBatch {
152
159
  transactions: BitcoinTransaction[];
153
160
  }
154
- export interface BitcoinSource {
161
+ export interface BitcoinSource extends SourceBase {
155
162
  readonly kind: "bitcoin";
156
- readonly name: string;
157
- getHeight(): Promise<number>;
158
163
  fetch(query: BitcoinQuery, options?: FetchOptions): AsyncIterable<BitcoinBatch>;
159
164
  }
160
- export type Source = EvmSource | BitcoinSource;
165
+ export interface SolanaQuery extends RangeQuery {
166
+ /** Wallets. Each one matches its own (SOL) account and every token account it owns. */
167
+ addresses: string[];
168
+ }
169
+ export interface SolanaBlock {
170
+ slot: number;
171
+ /** Unix seconds. */
172
+ time: number;
173
+ hash?: string;
174
+ parentHash?: string;
175
+ }
176
+ export interface SolanaTransaction {
177
+ /** The transaction id (its first signature). */
178
+ signature: string;
179
+ slot: number;
180
+ /** Order of the transaction inside its slot. */
181
+ transactionIndex: number;
182
+ feePayer: string;
183
+ /** Lamports, charged to the fee payer even when the transaction failed. */
184
+ fee: bigint;
185
+ success: boolean;
186
+ }
187
+ /** One account whose SOL or tokens changed in one transaction, before and after. */
188
+ export interface SolanaBalance {
189
+ signature: string;
190
+ slot: number;
191
+ transactionIndex: number;
192
+ account: string;
193
+ /** The account's lamports, when they changed. A token account holds its rent here, not its tokens. */
194
+ lamports?: {
195
+ pre: bigint;
196
+ post: bigint;
197
+ };
198
+ /** Set when the account is a token account: its tokens, in raw units. */
199
+ token?: {
200
+ mint: string;
201
+ owner: string;
202
+ decimals: number;
203
+ pre: bigint;
204
+ post: bigint;
205
+ };
206
+ }
207
+ export interface SolanaBatch extends RangeBatch {
208
+ blocks: SolanaBlock[];
209
+ transactions: SolanaTransaction[];
210
+ /** Changed balances of the queried wallets' accounts only (their SOL account and the token accounts they own). */
211
+ balances: SolanaBalance[];
212
+ }
213
+ export interface SolanaSource extends SourceBase {
214
+ readonly kind: "solana";
215
+ fetch(query: SolanaQuery, options?: FetchOptions): AsyncIterable<SolanaBatch>;
216
+ }
217
+ export type Source = EvmSource | BitcoinSource | SolanaSource;
161
218
  export type SourceKind = Source["kind"];
162
- export type QueryOf<S extends Source> = S extends EvmSource ? EvmQuery : BitcoinQuery;
163
- export type BatchOf<S extends Source> = S extends EvmSource ? EvmBatch : BitcoinBatch;
219
+ export type QueryOf<S extends Source> = S extends EvmSource ? EvmQuery : S extends BitcoinSource ? BitcoinQuery : SolanaQuery;
220
+ export type BatchOf<S extends Source> = S extends EvmSource ? EvmBatch : S extends BitcoinSource ? BitcoinBatch : SolanaBatch;
164
221
  /** Sort key for deterministic ordering of logs within a chain. */
165
222
  export declare function logOrder(a: EvmLog, b: EvmLog): number;
166
223
  export declare function txOrder(a: EvmTransaction, b: EvmTransaction): number;
167
224
  export declare function lower(s: string): string;
225
+ export {};
168
226
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Source abstraction. Every data provider (HyperSync, JSON-RPC, the cache
3
- * wrapper, Esplora for Bitcoin, recorded fixtures) implements the same
4
- * shape: `getHeight()` and `fetch(query)` yielding ordered, contiguous
3
+ * wrapper, Esplora for Bitcoin, Solana RPC, recorded fixtures) implements the
4
+ * same shape: `getHeight()` and `fetch(query)` yielding ordered, contiguous
5
5
  * batches of blocks/transactions/logs for a block range.
6
6
  */
7
7
  /** Sort key for deterministic ordering of logs within a chain. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqLH,kEAAkE;AAClE,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,CAAS;IAC3C,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;AAC7G,CAAC;AACD,MAAM,UAAU,OAAO,CAAC,CAAiB,EAAE,CAAiB;IAC1D,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+OH,kEAAkE;AAClE,MAAM,UAAU,QAAQ,CAAC,CAAS,EAAE,CAAS;IAC3C,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;AAC7G,CAAC;AACD,MAAM,UAAU,OAAO,CAAC,CAAiB,EAAE,CAAiB;IAC1D,OAAO,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,gBAAgB,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Source } from "./types.js";
2
+ /**
3
+ * Several sources of one chain as one. Each block range goes to the first source, in the given order, that holds
4
+ * it, so the usual shape is the fast source first and a complete one after it:
5
+ *
6
+ * union(hypersync({ kind: "solana" }), rpc({ kind: "solana", url })) // recent slots from HyperSync, older ones over RPC
7
+ *
8
+ * Where a source's data starts comes from its `firstBlock()`. A source is never asked for a range below it.
9
+ * The head (`getHeight`) is the first source's.
10
+ */
11
+ export declare function union<S extends Source>(...sources: [S, ...S[]]): S;
12
+ //# sourceMappingURL=union.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"union.d.ts","sourceRoot":"","sources":["../../src/sources/union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4C,MAAM,EAAE,MAAM,YAAY,CAAC;AAKnF;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAsDlE"}
@@ -0,0 +1,65 @@
1
+ /** History floors move (Solana HyperSync keeps backfilling), so they are read again this often. */
2
+ const FLOOR_TTL_MS = 60 * 60 * 1000;
3
+ /**
4
+ * Several sources of one chain as one. Each block range goes to the first source, in the given order, that holds
5
+ * it, so the usual shape is the fast source first and a complete one after it:
6
+ *
7
+ * union(hypersync({ kind: "solana" }), rpc({ kind: "solana", url })) // recent slots from HyperSync, older ones over RPC
8
+ *
9
+ * Where a source's data starts comes from its `firstBlock()`. A source is never asked for a range below it.
10
+ * The head (`getHeight`) is the first source's.
11
+ */
12
+ export function union(...sources) {
13
+ const kind = sources[0].kind;
14
+ const mixed = sources.find((s) => s.kind !== kind);
15
+ if (mixed)
16
+ throw new Error(`union(): ${mixed.name} is a ${mixed.kind} source, ${sources[0].name} is ${kind}`);
17
+ const floors = sources.map((source) => ({ source, value: 0, at: -Infinity }));
18
+ async function firstBlocks() {
19
+ const now = Date.now();
20
+ return Promise.all(floors.map(async (f) => {
21
+ if (!f.source.firstBlock || now - f.at < FLOOR_TTL_MS)
22
+ return f.value;
23
+ f.value = await f.source.firstBlock();
24
+ f.at = now;
25
+ return f.value;
26
+ }));
27
+ }
28
+ /** The source that serves `block` and where its turn ends: the next block a source before it starts at. */
29
+ function route(starts, block, toBlock) {
30
+ const i = starts.findIndex((start) => start <= block);
31
+ if (i === -1)
32
+ throw new Error(`union(): no source holds block ${block} (sources start at ${starts.join(", ")})`);
33
+ // Every source before `i` starts above `block`; the earliest of them takes over there.
34
+ return { source: sources[i], end: Math.min(toBlock, ...starts.slice(0, i)) };
35
+ }
36
+ const wrapped = {
37
+ kind,
38
+ name: `union(${sources.map((s) => s.name).join(", ")})`,
39
+ getHeight: () => sources[0].getHeight(),
40
+ async firstBlock() {
41
+ return Math.min(...(await firstBlocks()));
42
+ },
43
+ async *fetch(query, options) {
44
+ const starts = await firstBlocks();
45
+ let from = query.fromBlock;
46
+ while (from < query.toBlock) {
47
+ const { source, end } = route(starts, from, query.toBlock);
48
+ const fetch = source.fetch.bind(source);
49
+ yield* fetch({ ...query, fromBlock: from, toBlock: end }, options);
50
+ from = end;
51
+ }
52
+ },
53
+ };
54
+ if (kind === "evm") {
55
+ return {
56
+ ...wrapped,
57
+ async getBlock(number) {
58
+ const { source } = route(await firstBlocks(), number, number + 1);
59
+ return source.kind === "evm" ? source.getBlock?.(number) ?? null : null;
60
+ },
61
+ };
62
+ }
63
+ return wrapped;
64
+ }
65
+ //# sourceMappingURL=union.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"union.js","sourceRoot":"","sources":["../../src/sources/union.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { DatabaseConfig } from "../db/client.js";
2
- export { fixtureSource, readFixture, writeFixture, recordEvmFixture, recordBitcoinFixture } from "../sources/fixture.js";
3
- export type { Fixture, EvmFixture, BitcoinFixture } from "../sources/fixture.js";
2
+ export { fixtureSource, readFixture, writeFixture, recordEvmFixture, recordBitcoinFixture, recordSolanaFixture } from "../sources/fixture.js";
3
+ export type { Fixture, EvmFixture, BitcoinFixture, SolanaFixture } from "../sources/fixture.js";
4
4
  export { readMemoryLogs } from "evlog/memory";
5
5
  export { seedCache } from "../cache/cached.js";
6
6
  export interface TestClickHouse {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACzH,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;IAC3D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAoB7F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC9I,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;IAC3D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAoB7F"}
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- export { fixtureSource, readFixture, writeFixture, recordEvmFixture, recordBitcoinFixture } from "../sources/fixture.js";
2
+ export { fixtureSource, readFixture, writeFixture, recordEvmFixture, recordBitcoinFixture, recordSolanaFixture } from "../sources/fixture.js";
3
3
  export { readMemoryLogs } from "evlog/memory";
4
4
  export { seedCache } from "../cache/cached.js";
5
5
  let shared;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEzH,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU/C,IAAI,MAA2C,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAO,GAAuB,EAAE;IAClE,MAAM,KAAK,CAAC,KAAK,IAAI,EAAE;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;QACpD,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC,CAAC;QAChD,IAAI,mBAAyF,CAAC;QAC9F,IAAI,CAAC;YACH,CAAC,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,gLAAgL,EAChL,EAAE,KAAK,EAAE,CACV,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,mCAAmC,CAAC;aAC5I,YAAY,CAAC,SAAS,CAAC;aACvB,YAAY,CAAC,MAAM,CAAC;aACpB,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC,EAAE,CAAC;IACL,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,IAAyB;IAClD,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC,CAAC,QAAQ;QAAE,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;IACtD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,OAAO;QACL,GAAG,EAAE,IAAI;QACT,QAAQ,CAAC,MAAM;YACb,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC;QACrF,CAAC;QACD,IAAI;KACL,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE9I,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU/C,IAAI,MAA2C,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAO,GAAuB,EAAE;IAClE,MAAM,KAAK,CAAC,KAAK,IAAI,EAAE;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;QACpD,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC,CAAC;QAChD,IAAI,mBAAyF,CAAC;QAC9F,IAAI,CAAC;YACH,CAAC,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,gLAAgL,EAChL,EAAE,KAAK,EAAE,CACV,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,mCAAmC,CAAC;aAC5I,YAAY,CAAC,SAAS,CAAC;aACvB,YAAY,CAAC,MAAM,CAAC;aACpB,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC,EAAE,CAAC;IACL,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,IAAI,CAAC,GAAW,EAAE,IAAyB;IAClD,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC,CAAC,QAAQ;QAAE,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;IACtD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,OAAO;QACL,GAAG,EAAE,IAAI;QACT,QAAQ,CAAC,MAAM;YACb,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC;QACrF,CAAC;QACD,IAAI;KACL,CAAC;AACJ,CAAC"}
package/dist/util.d.ts CHANGED
@@ -1,9 +1,18 @@
1
1
  /** Wrap a single value in an array; copy an array. */
2
2
  export declare function toArray<T>(value: T | readonly T[]): T[];
3
+ /** Split a list into consecutive slices of at most `size` items. */
4
+ export declare function chunkList<T>(list: T[], size: number): T[][];
3
5
  /** JSON.stringify replacer that turns bigints into decimal strings. */
4
6
  export declare function bigintReplacer(_key: string, value: unknown): unknown;
5
7
  /** Lowercase a hex string, or null when absent. */
6
8
  export declare function lowerOrNull(value: string | null | undefined): string | null;
7
9
  /** URL-decode a credential from a URL, or fall back when the URL has none. */
8
10
  export declare function decodeOr(value: string, fallback: string): string;
11
+ /** Hex is case-insensitive and kept lowercase; base58 addresses (Solana, legacy Bitcoin) are not, and keep their case. */
12
+ export declare function normalizeHex(value: string): string;
13
+ /** `fn` over `items`, at most `limit` at a time, results in input order. */
14
+ export declare function mapLimit<T, R>(items: T[], limit: number, fn: (item: T) => Promise<R>): Promise<R[]>;
15
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
16
+ /** An HTTP response body, retried with backoff on 429, 5xx and network errors. Other statuses throw at once. */
17
+ export declare function request(doFetch: typeof fetch, url: string, init?: RequestInit): Promise<string>;
9
18
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAGvD;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAGpE;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAG3E;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGhE"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAGvD;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAK3D;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAGpE;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAG3E;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,0HAA0H;AAC1H,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,4EAA4E;AAC5E,wBAAsB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAYzG;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAQrE;AAED,gHAAgH;AAChH,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAazG"}
package/dist/util.js CHANGED
@@ -4,6 +4,15 @@ export function toArray(value) {
4
4
  return [...value];
5
5
  return [value];
6
6
  }
7
+ /** Split a list into consecutive slices of at most `size` items. */
8
+ export function chunkList(list, size) {
9
+ if (list.length === 0)
10
+ return [];
11
+ const out = [];
12
+ for (let i = 0; i < list.length; i += size)
13
+ out.push(list.slice(i, i + size));
14
+ return out;
15
+ }
7
16
  /** JSON.stringify replacer that turns bigints into decimal strings. */
8
17
  export function bigintReplacer(_key, value) {
9
18
  if (typeof value === "bigint")
@@ -22,4 +31,53 @@ export function decodeOr(value, fallback) {
22
31
  return decodeURIComponent(value);
23
32
  return fallback;
24
33
  }
34
+ /** Hex is case-insensitive and kept lowercase; base58 addresses (Solana, legacy Bitcoin) are not, and keep their case. */
35
+ export function normalizeHex(value) {
36
+ if (value.startsWith("0x"))
37
+ return value.toLowerCase();
38
+ return value;
39
+ }
40
+ /** `fn` over `items`, at most `limit` at a time, results in input order. */
41
+ export async function mapLimit(items, limit, fn) {
42
+ const out = new Array(items.length);
43
+ let next = 0;
44
+ await Promise.all(Array.from({ length: Math.min(limit, items.length) }, async () => {
45
+ while (next < items.length) {
46
+ const i = next++;
47
+ out[i] = await fn(items[i]);
48
+ }
49
+ }));
50
+ return out;
51
+ }
52
+ export function sleep(ms, signal) {
53
+ return new Promise((resolve, reject) => {
54
+ const t = setTimeout(resolve, ms);
55
+ signal?.addEventListener("abort", () => {
56
+ clearTimeout(t);
57
+ reject(signal.reason);
58
+ });
59
+ });
60
+ }
61
+ /** An HTTP response body, retried with backoff on 429, 5xx and network errors. Other statuses throw at once. */
62
+ export async function request(doFetch, url, init = {}) {
63
+ for (let attempt = 1;; attempt++) {
64
+ try {
65
+ const res = await doFetch(url, init);
66
+ if (res.ok)
67
+ return await res.text();
68
+ const body = await res.text().catch(() => "");
69
+ if (res.status !== 429 && res.status < 500)
70
+ throw new HttpError(`${url}: HTTP ${res.status} ${body.slice(0, 300)}`);
71
+ if (attempt === 12)
72
+ throw new Error(`${url}: HTTP ${res.status} after ${attempt} attempts`);
73
+ }
74
+ catch (err) {
75
+ if (err instanceof HttpError || init.signal?.aborted || attempt === 12)
76
+ throw err;
77
+ }
78
+ await sleep(Math.min(30_000, 250 * 2 ** attempt), init.signal ?? undefined);
79
+ }
80
+ }
81
+ class HttpError extends Error {
82
+ }
25
83
  //# sourceMappingURL=util.js.map
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,MAAM,UAAU,OAAO,CAAI,KAAuB;IAChD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,GAAI,KAAsB,CAAC,CAAC;IAC9D,OAAO,CAAC,KAAU,CAAC,CAAC;AACtB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAc;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IACvD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,KAAgC;IAC1D,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,QAAgB;IACtD,IAAI,KAAK;QAAE,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@notuslabs/yail",
3
- "version": "0.2.1",
4
- "description": "Blockchain indexer with Ponder-style DX: HyperSync as the primary EVM source, Esplora for Bitcoin, ClickHouse as the only storage",
3
+ "version": "0.3.0",
4
+ "description": "Blockchain indexer with Ponder-style DX: HyperSync as the primary EVM and Solana source, Esplora for Bitcoin, ClickHouse as the only storage",
5
5
  "keywords": [
6
6
  "indexer",
7
7
  "blockchain",
8
8
  "ethereum",
9
9
  "evm",
10
10
  "bitcoin",
11
+ "solana",
11
12
  "hypersync",
12
13
  "envio",
13
14
  "clickhouse",