@voidifydao/sdk 1.0.0 → 2.0.1
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 +0 -0
- package/dist/cli/config/init.js +1 -7
- package/dist/cli/config/loader.js +0 -1
- package/dist/cli/config/types.d.ts +0 -1
- package/dist/cli/deposit.js +45 -29
- package/dist/cli/helpers.js +0 -3
- package/dist/cli/progress.d.ts +5 -0
- package/dist/cli/progress.js +37 -0
- package/dist/cli/relayer.js +16 -7
- package/dist/cli/withdraw.js +20 -6
- package/dist/context.d.ts +1 -4
- package/dist/context.js +14 -12
- package/dist/idl/voidify/idl.d.ts +1 -1
- package/dist/idl/voidify/idl.json +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +0 -2
- package/dist/relayer/server/server.js +29 -13
- package/dist/relayer/server/switchboard.js +15 -6
- package/dist/relayer/types.d.ts +1 -0
- package/dist/substream/chain/index.d.ts +10 -3
- package/dist/substream/chain/index.js +14 -7
- package/dist/substream/chain/registry.d.ts +2 -2
- package/dist/substream/chain/utils.d.ts +2 -1
- package/dist/substream/chain/utils.js +35 -11
- package/dist/substream/client.d.ts +6 -1
- package/dist/substream/database/indexeddb.js +3 -0
- package/dist/substream/database/sqlite.d.ts +1 -0
- package/dist/substream/database/sqlite.js +6 -0
- package/dist/substream/modules/deposit.d.ts +2 -1
- package/dist/substream/modules/deposit.js +24 -20
- package/dist/substream/modules/relayer.d.ts +2 -1
- package/dist/substream/modules/relayer.js +39 -33
- package/dist/substream/runtime.d.ts +19 -4
- package/dist/substream/runtime.js +216 -16
- package/dist/substream/server/server.d.ts +2 -0
- package/dist/substream/server/server.js +42 -8
- package/dist/substream/types.d.ts +21 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +1 -1
- package/dist/voidify/deposit.d.ts +2 -0
- package/dist/voidify/deposit.js +1 -1
- package/dist/voidify/program.d.ts +0 -4
- package/dist/voidify/program.js +0 -10
- package/dist/voidify/relayer/list.d.ts +2 -0
- package/dist/voidify/relayer/list.js +1 -1
- package/dist/voidify/withdraw.d.ts +7 -2
- package/dist/voidify/withdraw.js +68 -10
- package/package.json +5 -4
- package/dist/idl/voidify-staking/idl.d.ts +0 -93
- package/dist/idl/voidify-staking/idl.js +0 -1
- package/dist/idl/voidify-staking/idl.json +0 -87
- package/dist/staking/commands.d.ts +0 -3
- package/dist/staking/commands.js +0 -13
- package/dist/staking/index.d.ts +0 -2
- package/dist/staking/index.js +0 -2
- package/dist/staking/program.d.ts +0 -18
- package/dist/staking/program.js +0 -40
- package/dist/types/errors.d.ts +0 -1
- package/dist/types/errors.js +0 -16
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Context } from "../../context.js";
|
|
2
2
|
import type { ChainEventRecord, EventProjection, EventScope, EventScopeType, EventStore, ProjectionStore } from "../../substream/types.js";
|
|
3
3
|
import type { VoidifyProgram } from "../../voidify/program.js";
|
|
4
|
-
import type { EventStreamSpec } from "./index.js";
|
|
4
|
+
import type { ChainSyncOptions, EventStreamSpec } from "./index.js";
|
|
5
5
|
export interface LiveEventContext {
|
|
6
6
|
ctx: Context;
|
|
7
7
|
voidify: VoidifyProgram;
|
|
@@ -18,7 +18,7 @@ export interface SubstreamModuleRuntime {
|
|
|
18
18
|
voidify: VoidifyProgram;
|
|
19
19
|
events: EventStore;
|
|
20
20
|
projections: ProjectionStore;
|
|
21
|
-
sync(scope: EventScope): Promise<void>;
|
|
21
|
+
sync(scope: EventScope, options?: ChainSyncOptions): Promise<void>;
|
|
22
22
|
rebuildProjection(scope: EventScope, projectionId: string): Promise<void>;
|
|
23
23
|
}
|
|
24
24
|
export interface SubstreamModule {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Connection, ConfirmedSignatureInfo, PublicKey } from "@solana/web3.js";
|
|
2
|
+
import type { SyncProgress } from "../../substream/types.js";
|
|
2
3
|
export declare function fetchSignaturesForAddress(connection: Connection, address: PublicKey, lastSignature?: string, batchSize?: number): Promise<ConfirmedSignatureInfo[]>;
|
|
3
4
|
export interface TransactionEvent {
|
|
4
5
|
signature: string;
|
|
@@ -6,4 +7,4 @@ export interface TransactionEvent {
|
|
|
6
7
|
slot: number | null;
|
|
7
8
|
blockTime: number | null;
|
|
8
9
|
}
|
|
9
|
-
export declare function
|
|
10
|
+
export declare function syncTransactionBatches(connection: Connection, address: PublicKey, lastSignature?: string, signatureBatchSize?: number, transactionBatchSize?: number, updateProgress?: (progress: SyncProgress) => void): AsyncGenerator<TransactionEvent[]>;
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import pRetry from "p-retry";
|
|
2
|
+
const retryConnection = (operation) => pRetry(operation, {
|
|
3
|
+
minTimeout: 1000,
|
|
4
|
+
retries: 5,
|
|
5
|
+
});
|
|
1
6
|
export async function fetchSignaturesForAddress(connection, address, lastSignature, batchSize = 1000) {
|
|
2
7
|
const signatures = [];
|
|
3
8
|
let beforeSignature = undefined;
|
|
4
9
|
while (true) {
|
|
5
|
-
const batch = await connection.getSignaturesForAddress(address, {
|
|
10
|
+
const batch = await retryConnection(() => connection.getSignaturesForAddress(address, {
|
|
6
11
|
limit: batchSize,
|
|
7
12
|
before: beforeSignature,
|
|
8
13
|
until: lastSignature,
|
|
9
|
-
});
|
|
14
|
+
}));
|
|
10
15
|
if (batch.length === 0)
|
|
11
16
|
break;
|
|
12
17
|
signatures.push(...batch);
|
|
@@ -17,25 +22,44 @@ export async function fetchSignaturesForAddress(connection, address, lastSignatu
|
|
|
17
22
|
signatures.reverse();
|
|
18
23
|
return signatures;
|
|
19
24
|
}
|
|
20
|
-
export async function
|
|
21
|
-
const signatures = await fetchSignaturesForAddress(connection, address, lastSignature,
|
|
25
|
+
export async function* syncTransactionBatches(connection, address, lastSignature, signatureBatchSize = 1000, transactionBatchSize = 50, updateProgress) {
|
|
26
|
+
const signatures = await fetchSignaturesForAddress(connection, address, lastSignature, signatureBatchSize);
|
|
22
27
|
if (signatures.length === 0) {
|
|
23
|
-
return
|
|
28
|
+
return;
|
|
24
29
|
}
|
|
25
30
|
const events = [];
|
|
31
|
+
let current = 0;
|
|
26
32
|
for (const sigInfo of signatures) {
|
|
27
|
-
const tx = await
|
|
28
|
-
|
|
33
|
+
const tx = await retryConnection(async () => {
|
|
34
|
+
const transaction = await connection.getTransaction(sigInfo.signature, {
|
|
35
|
+
maxSupportedTransactionVersion: 0,
|
|
36
|
+
});
|
|
37
|
+
if (!transaction?.meta) {
|
|
38
|
+
throw new Error(`transaction unavailable: ${sigInfo.signature}`);
|
|
39
|
+
}
|
|
40
|
+
return transaction;
|
|
29
41
|
});
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
const meta = tx.meta;
|
|
43
|
+
if (!meta) {
|
|
44
|
+
throw new Error(`transaction unavailable: ${sigInfo.signature}`);
|
|
32
45
|
}
|
|
33
46
|
events.push({
|
|
34
47
|
signature: sigInfo.signature,
|
|
35
|
-
logs:
|
|
48
|
+
logs: meta.logMessages || [],
|
|
36
49
|
slot: tx.slot ?? null,
|
|
37
50
|
blockTime: tx.blockTime ?? null,
|
|
38
51
|
});
|
|
52
|
+
current += 1;
|
|
53
|
+
updateProgress?.({
|
|
54
|
+
current,
|
|
55
|
+
total: signatures.length,
|
|
56
|
+
signature: sigInfo.signature,
|
|
57
|
+
});
|
|
58
|
+
if (events.length >= transactionBatchSize) {
|
|
59
|
+
yield events.splice(0, events.length);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (events.length > 0) {
|
|
63
|
+
yield events.splice(0, events.length);
|
|
39
64
|
}
|
|
40
|
-
return events;
|
|
41
65
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Context, SubstreamMode } from "../context.js";
|
|
2
|
-
import type { ChainEventWire, SubstreamRepos } from "../substream/types.js";
|
|
2
|
+
import type { ChainEventWire, SubstreamRepos, SyncStatus } from "../substream/types.js";
|
|
3
3
|
import type { BuiltinSubstreamModuleApis } from "../substream/modules/index.js";
|
|
4
4
|
export interface SubstreamCliConfig {
|
|
5
5
|
timeout?: number;
|
|
@@ -7,6 +7,8 @@ export interface SubstreamCliConfig {
|
|
|
7
7
|
healthCacheMs?: number;
|
|
8
8
|
}
|
|
9
9
|
export interface CursorWire {
|
|
10
|
+
scopeType: string;
|
|
11
|
+
scopeKey: string;
|
|
10
12
|
lastIndex: string | null;
|
|
11
13
|
lastSignature: string | null;
|
|
12
14
|
lastSyncAt: number;
|
|
@@ -15,6 +17,9 @@ export interface EventsApiResponse {
|
|
|
15
17
|
events: ChainEventWire[];
|
|
16
18
|
total: number;
|
|
17
19
|
cursor: CursorWire | null;
|
|
20
|
+
syncStatus: (Omit<SyncStatus, "cursor"> & {
|
|
21
|
+
cursor: CursorWire | null;
|
|
22
|
+
}) | null;
|
|
18
23
|
}
|
|
19
24
|
export declare class SubstreamCliClient {
|
|
20
25
|
private readonly runtime;
|
|
@@ -198,6 +198,9 @@ class IndexedDBProjectionStore {
|
|
|
198
198
|
async put(record) {
|
|
199
199
|
await this.getDb().projection_states.put(projectionStateToRow(record));
|
|
200
200
|
}
|
|
201
|
+
async delete(projectionId, key) {
|
|
202
|
+
await this.getDb().projection_states.delete([projectionId, key]);
|
|
203
|
+
}
|
|
201
204
|
async list(projectionId) {
|
|
202
205
|
const rows = await this.getDb()
|
|
203
206
|
.projection_states.where("projection_id")
|
|
@@ -20,6 +20,7 @@ export declare class SQLiteProjectionStore implements ProjectionStore {
|
|
|
20
20
|
initialize(): Promise<void>;
|
|
21
21
|
get(projectionId: string, key: string): Promise<ProjectionStateRecord | null>;
|
|
22
22
|
put(record: ProjectionStateRecord): Promise<void>;
|
|
23
|
+
delete(projectionId: string, key: string): Promise<void>;
|
|
23
24
|
list(projectionId: string): Promise<ProjectionStateRecord[]>;
|
|
24
25
|
clear(projectionId: string): Promise<void>;
|
|
25
26
|
}
|
|
@@ -241,6 +241,12 @@ export class SQLiteProjectionStore {
|
|
|
241
241
|
? null
|
|
242
242
|
: eventIndexToNumber(record.lastEventIndex));
|
|
243
243
|
}
|
|
244
|
+
async delete(projectionId, key) {
|
|
245
|
+
this.db
|
|
246
|
+
.prepare(`DELETE FROM projection_states
|
|
247
|
+
WHERE projection_id = ? AND entity_key = ?`)
|
|
248
|
+
.run(projectionId, key);
|
|
249
|
+
}
|
|
244
250
|
async list(projectionId) {
|
|
245
251
|
const rows = this.db
|
|
246
252
|
.prepare(`SELECT * FROM projection_states
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { DepositRecord, EventCursor, EventScope } from "../../substream/types.js";
|
|
2
2
|
import type { SubstreamModule } from "../../substream/chain/registry.js";
|
|
3
|
+
import type { ChainSyncOptions } from "../../substream/chain/index.js";
|
|
3
4
|
export interface DepositModuleApi {
|
|
4
|
-
sync(denomination: bigint): Promise<void>;
|
|
5
|
+
sync(denomination: bigint, options?: ChainSyncOptions): Promise<void>;
|
|
5
6
|
list(denomination: bigint, opts?: {
|
|
6
7
|
offset?: number;
|
|
7
8
|
limit?: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toBigInt } from "../../utils/anchor-events.js";
|
|
2
2
|
import { bytesToBigInt, bytesToHex } from "../../utils/bytes.js";
|
|
3
3
|
import { parseEventsFromLogs } from "../../utils/anchor-events.js";
|
|
4
|
-
import {
|
|
4
|
+
import { syncTransactionBatches, } from "../../substream/chain/utils.js";
|
|
5
5
|
export function depositScope(denomination) {
|
|
6
6
|
return { scopeType: "deposit", scopeKey: denomination.toString() };
|
|
7
7
|
}
|
|
@@ -35,8 +35,8 @@ export const depositModule = {
|
|
|
35
35
|
],
|
|
36
36
|
createClientApi(runtime) {
|
|
37
37
|
return {
|
|
38
|
-
async sync(denomination) {
|
|
39
|
-
await runtime.sync(depositScope(denomination));
|
|
38
|
+
async sync(denomination, options) {
|
|
39
|
+
await runtime.sync(depositScope(denomination), options);
|
|
40
40
|
},
|
|
41
41
|
async list(denomination, opts) {
|
|
42
42
|
const rows = await runtime.events.list(depositScope(denomination), opts);
|
|
@@ -65,27 +65,31 @@ function createDepositStream(ctx, voidify, denomination) {
|
|
|
65
65
|
const poolAccount = await voidify.program.account.pool.fetch(address);
|
|
66
66
|
return BigInt(poolAccount.merkleTree.nextIndex) - 1n;
|
|
67
67
|
},
|
|
68
|
-
|
|
69
|
-
const transactions
|
|
70
|
-
|
|
71
|
-
for (const tx of transactions) {
|
|
72
|
-
const decoded = parseEventsFromLogs(tx.logs, voidify.program.coder.events);
|
|
73
|
-
for (const item of decoded) {
|
|
74
|
-
if (item.name !== "depositEvent")
|
|
75
|
-
continue;
|
|
76
|
-
records.push(depositEventToChainEvent({
|
|
77
|
-
event: item.data,
|
|
78
|
-
signature: tx.signature,
|
|
79
|
-
slot: tx.slot,
|
|
80
|
-
blockTime: tx.blockTime,
|
|
81
|
-
address,
|
|
82
|
-
}));
|
|
83
|
-
}
|
|
68
|
+
collectBatches: async function* (lastSignature, run) {
|
|
69
|
+
for await (const transactions of syncTransactionBatches(ctx.connection, address, lastSignature, undefined, undefined, run?.updateProgress)) {
|
|
70
|
+
yield collectDepositRecords(transactions, voidify, address);
|
|
84
71
|
}
|
|
85
|
-
return records;
|
|
86
72
|
},
|
|
87
73
|
};
|
|
88
74
|
}
|
|
75
|
+
function collectDepositRecords(transactions, voidify, address) {
|
|
76
|
+
const records = [];
|
|
77
|
+
for (const tx of transactions) {
|
|
78
|
+
const decoded = parseEventsFromLogs(tx.logs, voidify.program.coder.events);
|
|
79
|
+
for (const item of decoded) {
|
|
80
|
+
if (item.name !== "depositEvent")
|
|
81
|
+
continue;
|
|
82
|
+
records.push(depositEventToChainEvent({
|
|
83
|
+
event: item.data,
|
|
84
|
+
signature: tx.signature,
|
|
85
|
+
slot: tx.slot,
|
|
86
|
+
blockTime: tx.blockTime,
|
|
87
|
+
address,
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return records;
|
|
92
|
+
}
|
|
89
93
|
function depositEventToChainEvent(args) {
|
|
90
94
|
const event = args.event;
|
|
91
95
|
const denomination = toBigInt(event.denomination);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { EventScope, RelayerRecord } from "../../substream/types.js";
|
|
2
2
|
import type { SubstreamModule } from "../../substream/chain/registry.js";
|
|
3
|
+
import type { ChainSyncOptions } from "../../substream/chain/index.js";
|
|
3
4
|
export interface RelayerModuleApi {
|
|
4
|
-
sync(): Promise<void>;
|
|
5
|
+
sync(options?: ChainSyncOptions): Promise<void>;
|
|
5
6
|
list(): Promise<RelayerRecord[]>;
|
|
6
7
|
get(pubkey: string): Promise<RelayerRecord | null>;
|
|
7
8
|
rebuild(): Promise<void>;
|
|
@@ -2,7 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
|
|
2
2
|
import { normalizePayload } from "../../substream/chain/events.js";
|
|
3
3
|
import { parseEventsFromLogs, } from "../../utils/anchor-events.js";
|
|
4
4
|
import { substreamLogger } from "../../utils/logger.js";
|
|
5
|
-
import {
|
|
5
|
+
import { syncTransactionBatches, } from "../../substream/chain/utils.js";
|
|
6
6
|
export const RELAYER_SCOPE = {
|
|
7
7
|
scopeType: "relayer",
|
|
8
8
|
scopeKey: "global",
|
|
@@ -32,7 +32,7 @@ export const relayerModule = {
|
|
|
32
32
|
const decoded = { name: eventName, data: event };
|
|
33
33
|
const pubkey = decoded.data.relayer.toBase58();
|
|
34
34
|
const cfg = decoded.name === "relayerRegisteredEvent"
|
|
35
|
-
? await fetchRelayerConfig(voidify, pubkey)
|
|
35
|
+
? await fetchRelayerConfig(voidify, pubkey, false)
|
|
36
36
|
: null;
|
|
37
37
|
return relayerEventToChainEvent({
|
|
38
38
|
event: decoded,
|
|
@@ -48,8 +48,8 @@ export const relayerModule = {
|
|
|
48
48
|
},
|
|
49
49
|
createClientApi(runtime) {
|
|
50
50
|
return {
|
|
51
|
-
async sync() {
|
|
52
|
-
await runtime.sync(RELAYER_SCOPE);
|
|
51
|
+
async sync(options) {
|
|
52
|
+
await runtime.sync(RELAYER_SCOPE, options);
|
|
53
53
|
},
|
|
54
54
|
async list() {
|
|
55
55
|
const rows = await runtime.projections.list("relayer");
|
|
@@ -75,33 +75,37 @@ function createRelayerStream(ctx, voidify) {
|
|
|
75
75
|
const counter = await voidify.program.account.relayerEventCounter.fetch(counterPda);
|
|
76
76
|
return BigInt(counter.count.toString()) - 1n;
|
|
77
77
|
},
|
|
78
|
-
|
|
79
|
-
const transactions
|
|
80
|
-
|
|
81
|
-
for (const tx of transactions) {
|
|
82
|
-
const decoded = parseEventsFromLogs(tx.logs, voidify.program.coder.events);
|
|
83
|
-
for (const item of decoded) {
|
|
84
|
-
if (!isIndexedRelayerEventName(item.name))
|
|
85
|
-
continue;
|
|
86
|
-
const event = item;
|
|
87
|
-
const pubkey = event.data.relayer.toBase58();
|
|
88
|
-
const cfg = event.name === "relayerRegisteredEvent"
|
|
89
|
-
? await fetchRelayerConfig(voidify, pubkey)
|
|
90
|
-
: null;
|
|
91
|
-
records.push(relayerEventToChainEvent({
|
|
92
|
-
event,
|
|
93
|
-
signature: tx.signature,
|
|
94
|
-
slot: tx.slot,
|
|
95
|
-
blockTime: tx.blockTime,
|
|
96
|
-
address: ctx.programId,
|
|
97
|
-
config: cfg,
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
78
|
+
collectBatches: async function* (lastSignature, run) {
|
|
79
|
+
for await (const transactions of syncTransactionBatches(ctx.connection, ctx.programId, lastSignature, undefined, undefined, run?.updateProgress)) {
|
|
80
|
+
yield await collectRelayerRecords(transactions, voidify, ctx.programId);
|
|
100
81
|
}
|
|
101
|
-
return records;
|
|
102
82
|
},
|
|
103
83
|
};
|
|
104
84
|
}
|
|
85
|
+
async function collectRelayerRecords(transactions, voidify, address) {
|
|
86
|
+
const records = [];
|
|
87
|
+
for (const tx of transactions) {
|
|
88
|
+
const decoded = parseEventsFromLogs(tx.logs, voidify.program.coder.events);
|
|
89
|
+
for (const item of decoded) {
|
|
90
|
+
if (!isIndexedRelayerEventName(item.name))
|
|
91
|
+
continue;
|
|
92
|
+
const event = item;
|
|
93
|
+
const pubkey = event.data.relayer.toBase58();
|
|
94
|
+
const cfg = event.name === "relayerRegisteredEvent"
|
|
95
|
+
? await fetchRelayerConfig(voidify, pubkey, true)
|
|
96
|
+
: null;
|
|
97
|
+
records.push(relayerEventToChainEvent({
|
|
98
|
+
event,
|
|
99
|
+
signature: tx.signature,
|
|
100
|
+
slot: tx.slot,
|
|
101
|
+
blockTime: tx.blockTime,
|
|
102
|
+
address,
|
|
103
|
+
config: cfg,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return records;
|
|
108
|
+
}
|
|
105
109
|
function relayerEventToChainEvent(args) {
|
|
106
110
|
const payload = normalizePayload(args.event.data);
|
|
107
111
|
if (args.event.name === "relayerRegisteredEvent") {
|
|
@@ -122,14 +126,16 @@ function relayerEventToChainEvent(args) {
|
|
|
122
126
|
function isIndexedRelayerEventName(name) {
|
|
123
127
|
return INDEXED_RELAYER_EVENT_NAMES.has(name);
|
|
124
128
|
}
|
|
125
|
-
async function fetchRelayerConfig(voidify, relayerPubkey) {
|
|
129
|
+
async function fetchRelayerConfig(voidify, relayerPubkey, quietNotFound = false) {
|
|
126
130
|
try {
|
|
127
131
|
const cfgKey = voidify.relayerConfig(new PublicKey(relayerPubkey));
|
|
128
132
|
const cfg = await voidify.program.account.relayerConfig.fetch(cfgKey);
|
|
129
133
|
return { name: cfg.name, url: cfg.url, feeBps: cfg.feeBps };
|
|
130
134
|
}
|
|
131
135
|
catch (err) {
|
|
132
|
-
|
|
136
|
+
if (!quietNotFound) {
|
|
137
|
+
substreamLogger.warn({ err, relayerPubkey }, "fetchRelayerConfig failed");
|
|
138
|
+
}
|
|
133
139
|
return null;
|
|
134
140
|
}
|
|
135
141
|
}
|
|
@@ -151,8 +157,10 @@ class RelayerProjection {
|
|
|
151
157
|
const existing = await this.store.get(this.id, pubkey);
|
|
152
158
|
const current = existing ? valueToRelayerState(existing.value) : null;
|
|
153
159
|
const next = reduceRelayerEvent(current, event);
|
|
154
|
-
if (!next)
|
|
160
|
+
if (!next) {
|
|
161
|
+
await this.store.delete(this.id, pubkey);
|
|
155
162
|
continue;
|
|
163
|
+
}
|
|
156
164
|
await this.store.put({
|
|
157
165
|
projectionId: this.id,
|
|
158
166
|
key: pubkey,
|
|
@@ -202,9 +210,7 @@ function reduceRelayerEvent(existing, event) {
|
|
|
202
210
|
}
|
|
203
211
|
case "relayerSlashedEvent":
|
|
204
212
|
case "relayerUnregisteredEvent": {
|
|
205
|
-
|
|
206
|
-
record.isActive = false;
|
|
207
|
-
break;
|
|
213
|
+
return null;
|
|
208
214
|
}
|
|
209
215
|
case "relayerUpdatedEvent": {
|
|
210
216
|
if (event.payload.feeBps !== null && event.payload.feeBps !== undefined) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Context, SubstreamMode } from "../context.js";
|
|
2
|
-
import type { EventScope, EventStore, ProjectionStore, SubstreamStores } from "../substream/types.js";
|
|
3
|
-
import { ChainEventSyncer, ProjectionRegistry } from "../substream/chain/index.js";
|
|
2
|
+
import type { EventScope, EventStore, ProjectionStore, SyncStatus, SubstreamStores } from "../substream/types.js";
|
|
3
|
+
import { type ChainSyncOptions, ChainEventSyncer, ProjectionRegistry } from "../substream/chain/index.js";
|
|
4
4
|
import { SubstreamModuleRegistry, type SubstreamModule, type SubstreamModuleRuntime } from "../substream/chain/registry.js";
|
|
5
5
|
import { VoidifyProgram } from "../voidify/program.js";
|
|
6
6
|
export interface SubstreamRuntimeConfig {
|
|
@@ -19,20 +19,35 @@ export declare class SubstreamRuntime implements SubstreamModuleRuntime {
|
|
|
19
19
|
private readonly mode;
|
|
20
20
|
private readonly timeout;
|
|
21
21
|
private readonly healthCacheMs;
|
|
22
|
+
private readonly syncInFlight;
|
|
23
|
+
private readonly syncStatuses;
|
|
22
24
|
private healthState;
|
|
23
25
|
private initialized;
|
|
24
26
|
constructor(ctx: Context, stores: SubstreamStores, config?: SubstreamRuntimeConfig, modules?: readonly SubstreamModule[]);
|
|
25
27
|
initialize(): Promise<void>;
|
|
26
28
|
module(id: string): unknown;
|
|
27
|
-
sync(scope: EventScope): Promise<void>;
|
|
28
|
-
syncLocal(scope: EventScope): Promise<void>;
|
|
29
|
+
sync(scope: EventScope, options?: ChainSyncOptions): Promise<void>;
|
|
30
|
+
syncLocal(scope: EventScope, options?: ChainSyncOptions): Promise<void>;
|
|
31
|
+
syncLocalInBackground(scope: EventScope): SyncStatus;
|
|
29
32
|
applyLiveEvent(eventScope: EventScope): Promise<void>;
|
|
30
33
|
applyLiveRecord(scope: EventScope, record: Parameters<ChainEventSyncer["applyLiveEvent"]>[1]): Promise<void>;
|
|
31
34
|
rebuildProjection(scope: EventScope, projectionId: string): Promise<void>;
|
|
35
|
+
getSyncStatus(scope: EventScope, mode?: "local" | "remote"): SyncStatus;
|
|
32
36
|
private get baseUrl();
|
|
33
37
|
private resolveMode;
|
|
34
38
|
private healthCheck;
|
|
35
39
|
private syncRemote;
|
|
40
|
+
private applyRemoteEvents;
|
|
41
|
+
private runScopedSync;
|
|
42
|
+
private syncKey;
|
|
43
|
+
private ensureSyncStatus;
|
|
44
|
+
private setSyncStatus;
|
|
45
|
+
private updateSyncStatus;
|
|
46
|
+
private waitForRemoteSync;
|
|
47
|
+
private sleep;
|
|
36
48
|
private fetchRemoteEvents;
|
|
49
|
+
private remoteEventsUrl;
|
|
50
|
+
private fetchWithTimeout;
|
|
51
|
+
private fetchRemoteSyncStatus;
|
|
37
52
|
}
|
|
38
53
|
export declare function createSubstreamRuntime(ctx: Context, stores: SubstreamStores, config?: SubstreamRuntimeConfig, modules?: readonly SubstreamModule[]): SubstreamRuntime;
|