@subsquid/portal-client 0.0.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.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @subsquid/portal-client
2
+
3
+ API for SQD Portal.
@@ -0,0 +1,102 @@
1
+ import { HttpClient, HttpClientOptions } from '@subsquid/http-client';
2
+ import { evm, PortalBlock, PortalQuery, solana, substrate } from './query';
3
+ import { Simplify } from './query/common';
4
+ export type * from './query';
5
+ export interface PortalClientOptions {
6
+ /**
7
+ * The URL of the portal dataset.
8
+ */
9
+ url: string;
10
+ /**
11
+ * Optional custom HTTP client to use.
12
+ */
13
+ http?: HttpClient | HttpClientOptions;
14
+ /**
15
+ * Minimum number of bytes to return.
16
+ * @default 10_485_760 (10MB)
17
+ */
18
+ minBytes?: number;
19
+ /**
20
+ * Maximum number of bytes to return.
21
+ * @default minBytes
22
+ */
23
+ maxBytes?: number;
24
+ /**
25
+ * Maximum time between stream data in milliseconds for return.
26
+ * @default 300
27
+ */
28
+ maxIdleTime?: number;
29
+ /**
30
+ * Maximum wait time in milliseconds for return.
31
+ * @default 5_000
32
+ */
33
+ maxWaitTime?: number;
34
+ /**
35
+ * Interval for polling the head in milliseconds.
36
+ * @default 0
37
+ */
38
+ headPollInterval?: number;
39
+ }
40
+ export interface PortalRequestOptions {
41
+ headers?: HeadersInit;
42
+ retryAttempts?: number;
43
+ retrySchedule?: number[];
44
+ httpTimeout?: number;
45
+ bodyTimeout?: number;
46
+ abort?: AbortSignal;
47
+ }
48
+ export interface PortalStreamOptions {
49
+ request?: Omit<PortalRequestOptions, 'abort'>;
50
+ minBytes?: number;
51
+ maxBytes?: number;
52
+ maxIdleTime?: number;
53
+ maxWaitTime?: number;
54
+ headPollInterval?: number;
55
+ }
56
+ export type PortalStreamData<B> = {
57
+ blocks: B[];
58
+ finalizedHead?: BlockRef;
59
+ meta: {
60
+ bytes: number;
61
+ };
62
+ };
63
+ export interface PortalStream<B> extends AsyncIterable<PortalStreamData<B>> {
64
+ }
65
+ export type GetBlock<Q extends evm.Query | solana.Query | substrate.Query> = Q['type'] extends 'evm' ? evm.Block<Q['fields']> : Q['type'] extends 'solana' ? solana.Block<Q['fields']> : Q['type'] extends 'substrate' ? substrate.Block<Q['fields']> : PortalBlock;
66
+ export type BlockRef = {
67
+ hash: string;
68
+ number: number;
69
+ };
70
+ export declare function createQuery<Q extends evm.Query | solana.Query | substrate.Query>(query: Q): Simplify<Q & PortalQuery>;
71
+ export declare class PortalClient {
72
+ private url;
73
+ private client;
74
+ private headPollInterval;
75
+ private minBytes;
76
+ private maxBytes;
77
+ private maxIdleTime;
78
+ private maxWaitTime;
79
+ constructor(options: PortalClientOptions);
80
+ private getDatasetUrl;
81
+ getHead(options?: PortalRequestOptions): Promise<BlockRef | undefined>;
82
+ getFinalizedHead(options?: PortalRequestOptions): Promise<BlockRef | undefined>;
83
+ /**
84
+ * @deprecated
85
+ */
86
+ getFinalizedHeight(options?: PortalRequestOptions): Promise<number>;
87
+ getFinalizedQuery<Q extends evm.Query | solana.Query | substrate.Query, R extends GetBlock<Q> = GetBlock<Q>>(query: Q, options?: PortalRequestOptions): Promise<R[]>;
88
+ getQuery<Q extends PortalQuery = PortalQuery, R extends PortalBlock = PortalBlock>(query: Q, options?: PortalRequestOptions): Promise<R[]>;
89
+ getFinalizedStream<Q extends evm.Query | solana.Query | substrate.Query, R extends GetBlock<Q> = GetBlock<Q>>(query: Q, options?: PortalStreamOptions): PortalStream<R>;
90
+ getStream<Q extends evm.Query | solana.Query | substrate.Query, R extends GetBlock<Q> = GetBlock<Q>>(query: Q, options?: PortalStreamOptions): PortalStream<R>;
91
+ private getStreamOptions;
92
+ private getStreamRequest;
93
+ private request;
94
+ }
95
+ export declare class ForkException extends Error {
96
+ readonly lastBlocks: BlockRef[];
97
+ readonly head: BlockRef;
98
+ readonly name = "ForkError";
99
+ constructor(lastBlocks: BlockRef[], head: BlockRef);
100
+ }
101
+ export declare function isForkException(err: unknown): err is ForkException;
102
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAE,iBAAiB,EAA0C,MAAM,uBAAuB,CAAA;AAWtH,OAAO,EAAC,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAC,MAAM,SAAS,CAAA;AACxE,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AAEvC,mBAAmB,SAAS,CAAA;AAI5B,MAAM,WAAW,mBAAmB;IAChC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;OAEG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,iBAAiB,CAAA;IAErC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,WAAW,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAA;IAE7C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAC9B,MAAM,EAAE,CAAC,EAAE,CAAA;IACX,aAAa,CAAC,EAAE,QAAQ,CAAA;IACxB,IAAI,EAAE;QACF,KAAK,EAAE,MAAM,CAAA;KAChB,CAAA;CACJ,CAAA;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAAG;AAE9E,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,KAAK,GAC9F,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GACtB,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GACzB,CAAC,CAAC,MAAM,CAAC,SAAS,WAAW,GAC7B,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAC5B,WAAW,CAAA;AAEjB,MAAM,MAAM,QAAQ,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,WAAW,CAAC,CAErH;AAED,qBAAa,YAAY;IACrB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,WAAW,CAAQ;gBAEf,OAAO,EAAE,mBAAmB;IAUxC,OAAO,CAAC,aAAa;IAUf,OAAO,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAKtE,gBAAgB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAKrF;;OAEG;IACG,kBAAkB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC;IAMzE,iBAAiB,CAAC,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,EACvG,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,oBAAoB,GAC/B,OAAO,CAAC,CAAC,EAAE,CAAC;IAqBf,QAAQ,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,CAAC,SAAS,WAAW,GAAG,WAAW,EAC7E,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,oBAAoB,GAC/B,OAAO,CAAC,CAAC,EAAE,CAAC;IAqBf,kBAAkB,CAAC,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,EACxG,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,mBAAmB,GAC9B,YAAY,CAAC,CAAC,CAAC;IAMlB,SAAS,CAAC,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,EAC/F,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE,mBAAmB,GAC9B,YAAY,CAAC,CAAC,CAAC;IAMlB,OAAO,CAAC,gBAAgB;YAoBV,gBAAgB;IA0C9B,OAAO,CAAC,OAAO;CASlB;AAgTD,qBAAa,aAAc,SAAQ,KAAK;IAGxB,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ;IAFpE,QAAQ,CAAC,IAAI,eAAc;gBAEN,UAAU,EAAE,QAAQ,EAAE,EAAW,IAAI,EAAE,QAAQ;CAQvE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,aAAa,CAIlE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client.example.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.example.d.ts","sourceRoot":"","sources":["../src/client.example.ts"],"names":[],"mappings":""}
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const client_1 = require("./client");
4
+ const portalUrls = {
5
+ evm: 'https://portal.sqd.dev/datasets/ethereum-mainnet',
6
+ solana: 'https://portal.sqd.dev/datasets/solana-mainnet',
7
+ };
8
+ const queries = {
9
+ evm: (0, client_1.createQuery)({
10
+ type: 'evm',
11
+ fromBlock: 23000000,
12
+ fields: {
13
+ block: {
14
+ number: true,
15
+ hash: true,
16
+ timestamp: true,
17
+ },
18
+ transaction: {
19
+ from: true,
20
+ to: true,
21
+ hash: true,
22
+ },
23
+ log: {
24
+ address: true,
25
+ topics: true,
26
+ data: true,
27
+ transactionHash: true,
28
+ logIndex: true,
29
+ transactionIndex: true,
30
+ },
31
+ stateDiff: {
32
+ kind: true,
33
+ next: true,
34
+ prev: true,
35
+ },
36
+ },
37
+ logs: [
38
+ {
39
+ address: ['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'],
40
+ topic0: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'],
41
+ },
42
+ ],
43
+ }),
44
+ solana: (0, client_1.createQuery)({
45
+ type: 'solana',
46
+ fromBlock: 358600000,
47
+ fields: {
48
+ block: { number: true, timestamp: true, hash: true, parentHash: true },
49
+ transaction: { signatures: true, err: true, transactionIndex: true },
50
+ instruction: {
51
+ programId: true,
52
+ accounts: true,
53
+ data: true,
54
+ isCommitted: true,
55
+ transactionIndex: true,
56
+ instructionAddress: true,
57
+ },
58
+ },
59
+ instructions: [
60
+ {
61
+ programId: ['whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc'],
62
+ d8: ['0xf8c69e91e17587c8'],
63
+ isCommitted: true,
64
+ innerInstructions: true,
65
+ },
66
+ ],
67
+ }),
68
+ };
69
+ async function main() {
70
+ const queryType = 'evm';
71
+ const query = queries[queryType];
72
+ let portal = new client_1.PortalClient({
73
+ url: portalUrls[queryType],
74
+ http: {
75
+ retryAttempts: Infinity,
76
+ },
77
+ minBytes: 50 * 1024 * 1024,
78
+ });
79
+ let coldHead = undefined;
80
+ let hotHeads = [];
81
+ while (true) {
82
+ const currentQuery = { ...query };
83
+ let head = hotHeads[hotHeads.length - 1] ?? coldHead;
84
+ if (head != null && head.number > currentQuery.fromBlock) {
85
+ currentQuery.fromBlock = head.number + 1;
86
+ currentQuery.parentBlockHash = head.hash;
87
+ }
88
+ try {
89
+ for await (let { blocks, finalizedHead } of portal.getStream(query)) {
90
+ if (head && blocks.length > 0 && head.number >= blocks[0].header.number) {
91
+ throw new Error('Data is not continuous');
92
+ }
93
+ let unfinalizedIndex = 0;
94
+ if (finalizedHead) {
95
+ unfinalizedIndex = blocks.findIndex((b) => b.header.number > finalizedHead?.number);
96
+ }
97
+ // all new blocks are finalized
98
+ if (unfinalizedIndex < 0) {
99
+ const finalizedRef = blocks[blocks.length - 1].header;
100
+ coldHead = { number: finalizedRef.number, hash: finalizedRef.hash };
101
+ // finalize all hot heads
102
+ hotHeads = [];
103
+ }
104
+ else {
105
+ const finalizedRef = finalizedHead ?? blocks[unfinalizedIndex - 1]?.header;
106
+ coldHead = finalizedRef ?? coldHead;
107
+ // finalize all hot heads that are older than the cold head
108
+ if (coldHead) {
109
+ let finalizeIndex = hotHeads.findIndex((h) => h.number > coldHead.number);
110
+ hotHeads = finalizeIndex < 0 ? [] : hotHeads.slice(finalizeIndex);
111
+ }
112
+ // process unfinalized blocks
113
+ for (let i = unfinalizedIndex; i < blocks.length; i++) {
114
+ hotHeads.push({ number: blocks[i].header.number, hash: blocks[i].header.hash });
115
+ }
116
+ }
117
+ head = hotHeads[hotHeads.length - 1] ?? coldHead;
118
+ let portalHead = Math.max(head.number, finalizedHead?.number ?? -1);
119
+ console.log(`progress: ${head.number} / ${portalHead}` + `, blocks: ${blocks.length}`);
120
+ console.log(` \u001b[2mcold head: ${coldHead ? formatRef(coldHead) : 'N/A'}\u001b[0m`);
121
+ console.log(` \u001b[2mhot heads: ${hotHeads.map((h) => formatRef(h)).join(', ') || 'N/A'}\u001b[0m`);
122
+ }
123
+ break;
124
+ }
125
+ catch (e) {
126
+ if (!(0, client_1.isForkException)(e))
127
+ throw e;
128
+ let chain = coldHead ? [coldHead, ...hotHeads] : hotHeads;
129
+ let rollbackIndex = findRollbackIndex(chain, e.lastBlocks);
130
+ if (rollbackIndex === -1)
131
+ throw new Error('Unable to process fork');
132
+ const rollbackHead = chain[rollbackIndex];
133
+ console.warn(`detected fork at block ${rollbackHead.number} (${e.head.number - rollbackHead.number} depth)`);
134
+ hotHeads = chain.slice(1, rollbackIndex + 1);
135
+ head = hotHeads[hotHeads.length - 1] ?? coldHead;
136
+ }
137
+ }
138
+ }
139
+ function findRollbackIndex(chainA, chainB) {
140
+ let i = 0;
141
+ let j = 0;
142
+ for (; i < chainA.length; i++) {
143
+ const blockA = chainA[i];
144
+ for (; j < chainB.length; j++) {
145
+ let blockB = chainB[j];
146
+ if (blockB.number > blockA.number)
147
+ break;
148
+ if (blockB.number === blockA.number && blockB.hash !== blockA.hash)
149
+ return i - 1;
150
+ }
151
+ }
152
+ return i - 1;
153
+ }
154
+ function formatRef(ref) {
155
+ return `${ref.number}#${ref.hash.slice(2, 8)}`;
156
+ }
157
+ main();
158
+ //# sourceMappingURL=client.example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.example.js","sourceRoot":"","sources":["../src/client.example.ts"],"names":[],"mappings":"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"}