@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
|
@@ -14,6 +14,8 @@ export class SubstreamRuntime {
|
|
|
14
14
|
mode;
|
|
15
15
|
timeout;
|
|
16
16
|
healthCacheMs;
|
|
17
|
+
syncInFlight = new Map();
|
|
18
|
+
syncStatuses = new Map();
|
|
17
19
|
healthState = null;
|
|
18
20
|
initialized = false;
|
|
19
21
|
constructor(ctx, stores, config, modules) {
|
|
@@ -47,19 +49,19 @@ export class SubstreamRuntime {
|
|
|
47
49
|
}
|
|
48
50
|
return module.createClientApi(this);
|
|
49
51
|
}
|
|
50
|
-
async sync(scope) {
|
|
52
|
+
async sync(scope, options) {
|
|
51
53
|
const mode = await this.resolveMode();
|
|
52
54
|
if (mode === "local") {
|
|
53
|
-
await this.syncLocal(scope);
|
|
55
|
+
await this.syncLocal(scope, options);
|
|
54
56
|
return;
|
|
55
57
|
}
|
|
56
58
|
try {
|
|
57
|
-
await this.syncRemote(scope);
|
|
59
|
+
await this.syncRemote(scope, options);
|
|
58
60
|
}
|
|
59
61
|
catch (error) {
|
|
60
62
|
if (this.mode === "auto") {
|
|
61
63
|
this.healthState = { ok: false, checkedAt: Date.now() };
|
|
62
|
-
await this.syncLocal(scope);
|
|
64
|
+
await this.syncLocal(scope, options);
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -68,8 +70,24 @@ export class SubstreamRuntime {
|
|
|
68
70
|
});
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
|
-
async syncLocal(scope) {
|
|
72
|
-
await this.syncer.checkAndSync(this.registry.createStream(this.ctx, this.voidify, scope));
|
|
73
|
+
async syncLocal(scope, options) {
|
|
74
|
+
await this.runScopedSync(scope, "local", options, (run) => this.syncer.checkAndSync(this.registry.createStream(this.ctx, this.voidify, scope), run));
|
|
75
|
+
}
|
|
76
|
+
syncLocalInBackground(scope) {
|
|
77
|
+
const key = this.syncKey(scope, "local");
|
|
78
|
+
const running = this.syncInFlight.get(key);
|
|
79
|
+
if (!running) {
|
|
80
|
+
this.setSyncStatus(scope, "local", {
|
|
81
|
+
phase: "checking",
|
|
82
|
+
running: true,
|
|
83
|
+
progress: null,
|
|
84
|
+
error: null,
|
|
85
|
+
startedAt: Date.now(),
|
|
86
|
+
completedAt: null,
|
|
87
|
+
});
|
|
88
|
+
void this.syncLocal(scope).catch(() => undefined);
|
|
89
|
+
}
|
|
90
|
+
return this.getSyncStatus(scope, "local");
|
|
73
91
|
}
|
|
74
92
|
async applyLiveEvent(eventScope) {
|
|
75
93
|
await this.syncLocal(eventScope);
|
|
@@ -86,6 +104,17 @@ export class SubstreamRuntime {
|
|
|
86
104
|
const events = await this.events.getAfter(scope);
|
|
87
105
|
await projection.apply(events.filter((event) => projection.matches(event)));
|
|
88
106
|
}
|
|
107
|
+
getSyncStatus(scope, mode = "local") {
|
|
108
|
+
const status = this.ensureSyncStatus(scope, mode);
|
|
109
|
+
if (status.running && !this.syncInFlight.has(this.syncKey(scope, mode))) {
|
|
110
|
+
return this.setSyncStatus(scope, mode, {
|
|
111
|
+
phase: status.error ? "failed" : "complete",
|
|
112
|
+
running: false,
|
|
113
|
+
completedAt: status.completedAt ?? Date.now(),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return status;
|
|
117
|
+
}
|
|
89
118
|
get baseUrl() {
|
|
90
119
|
const s = this.ctx.substream;
|
|
91
120
|
if (s.type === "local") {
|
|
@@ -126,10 +155,22 @@ export class SubstreamRuntime {
|
|
|
126
155
|
return false;
|
|
127
156
|
}
|
|
128
157
|
}
|
|
129
|
-
async syncRemote(scope) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
158
|
+
async syncRemote(scope, options) {
|
|
159
|
+
await this.runScopedSync(scope, "remote", options, async () => {
|
|
160
|
+
const cursor = await this.events.getCursor(scope);
|
|
161
|
+
const afterIndex = cursor?.lastIndex ?? null;
|
|
162
|
+
const response = await this.fetchRemoteEvents(scope, afterIndex, "background");
|
|
163
|
+
await this.applyRemoteEvents(scope, response.events, afterIndex);
|
|
164
|
+
if (response.syncStatus?.running) {
|
|
165
|
+
await this.waitForRemoteSync(scope, options);
|
|
166
|
+
const nextCursor = await this.events.getCursor(scope);
|
|
167
|
+
const nextAfterIndex = nextCursor?.lastIndex ?? null;
|
|
168
|
+
const nextResponse = await this.fetchRemoteEvents(scope, nextAfterIndex, "skip");
|
|
169
|
+
await this.applyRemoteEvents(scope, nextResponse.events, nextAfterIndex);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async applyRemoteEvents(scope, events, afterIndex) {
|
|
133
174
|
const newEvents = events.filter((event) => afterIndex === null || event.eventIndex > afterIndex);
|
|
134
175
|
if (newEvents.length === 0)
|
|
135
176
|
return;
|
|
@@ -139,25 +180,184 @@ export class SubstreamRuntime {
|
|
|
139
180
|
}
|
|
140
181
|
await this.projectionRegistry.apply(newEvents);
|
|
141
182
|
}
|
|
142
|
-
async
|
|
183
|
+
async runScopedSync(scope, mode, options, task) {
|
|
184
|
+
const key = this.syncKey(scope, mode);
|
|
185
|
+
const running = this.syncInFlight.get(key);
|
|
186
|
+
if (running) {
|
|
187
|
+
options?.reporter?.update(this.ensureSyncStatus(scope, mode));
|
|
188
|
+
await running;
|
|
189
|
+
options?.reporter?.update(this.ensureSyncStatus(scope, mode));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const pending = Promise.resolve().then(async () => {
|
|
193
|
+
options?.reporter?.update(await this.updateSyncStatus(scope, mode, {
|
|
194
|
+
phase: "checking",
|
|
195
|
+
running: true,
|
|
196
|
+
progress: null,
|
|
197
|
+
cursor: await this.events.getCursor(scope),
|
|
198
|
+
error: null,
|
|
199
|
+
startedAt: Date.now(),
|
|
200
|
+
completedAt: null,
|
|
201
|
+
}));
|
|
202
|
+
await task({
|
|
203
|
+
updateProgress: (progress) => {
|
|
204
|
+
void this.updateSyncStatus(scope, mode, {
|
|
205
|
+
phase: "syncing",
|
|
206
|
+
running: true,
|
|
207
|
+
progress,
|
|
208
|
+
}).then((status) => options?.reporter?.update(status));
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
options?.reporter?.update(await this.updateSyncStatus(scope, mode, {
|
|
212
|
+
phase: "complete",
|
|
213
|
+
running: false,
|
|
214
|
+
cursor: await this.events.getCursor(scope),
|
|
215
|
+
completedAt: Date.now(),
|
|
216
|
+
}));
|
|
217
|
+
});
|
|
218
|
+
this.syncInFlight.set(key, pending);
|
|
219
|
+
try {
|
|
220
|
+
options?.reporter?.update(this.ensureSyncStatus(scope, mode));
|
|
221
|
+
await pending;
|
|
222
|
+
options?.reporter?.update(this.ensureSyncStatus(scope, mode));
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
await this.updateSyncStatus(scope, mode, {
|
|
226
|
+
phase: "failed",
|
|
227
|
+
running: false,
|
|
228
|
+
error: error instanceof Error ? error.message : String(error),
|
|
229
|
+
cursor: await this.events.getCursor(scope),
|
|
230
|
+
completedAt: Date.now(),
|
|
231
|
+
});
|
|
232
|
+
options?.reporter?.update(this.ensureSyncStatus(scope, mode));
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
if (this.syncInFlight.get(key) === pending) {
|
|
237
|
+
this.syncInFlight.delete(key);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
syncKey(scope, mode) {
|
|
242
|
+
return `${mode}:${scope.scopeType}:${scope.scopeKey}`;
|
|
243
|
+
}
|
|
244
|
+
ensureSyncStatus(scope, mode) {
|
|
245
|
+
const key = this.syncKey(scope, mode);
|
|
246
|
+
const status = this.syncStatuses.get(key);
|
|
247
|
+
if (status)
|
|
248
|
+
return status;
|
|
249
|
+
const initial = {
|
|
250
|
+
...scope,
|
|
251
|
+
mode,
|
|
252
|
+
phase: "idle",
|
|
253
|
+
running: false,
|
|
254
|
+
progress: null,
|
|
255
|
+
cursor: null,
|
|
256
|
+
error: null,
|
|
257
|
+
startedAt: null,
|
|
258
|
+
updatedAt: Date.now(),
|
|
259
|
+
completedAt: null,
|
|
260
|
+
};
|
|
261
|
+
this.syncStatuses.set(key, initial);
|
|
262
|
+
return initial;
|
|
263
|
+
}
|
|
264
|
+
setSyncStatus(scope, mode, patch) {
|
|
265
|
+
const current = this.ensureSyncStatus(scope, mode);
|
|
266
|
+
const next = {
|
|
267
|
+
...current,
|
|
268
|
+
...patch,
|
|
269
|
+
updatedAt: Date.now(),
|
|
270
|
+
};
|
|
271
|
+
this.syncStatuses.set(this.syncKey(scope, mode), next);
|
|
272
|
+
return next;
|
|
273
|
+
}
|
|
274
|
+
async updateSyncStatus(scope, mode, patch) {
|
|
275
|
+
return this.setSyncStatus(scope, mode, patch);
|
|
276
|
+
}
|
|
277
|
+
async waitForRemoteSync(scope, options) {
|
|
278
|
+
while (true) {
|
|
279
|
+
await this.sleep(1000);
|
|
280
|
+
const status = await this.fetchRemoteSyncStatus(scope);
|
|
281
|
+
options?.reporter?.update(await this.updateSyncStatus(scope, "remote", {
|
|
282
|
+
phase: status.phase,
|
|
283
|
+
running: status.running,
|
|
284
|
+
progress: status.progress,
|
|
285
|
+
error: status.error,
|
|
286
|
+
startedAt: status.startedAt,
|
|
287
|
+
completedAt: status.completedAt,
|
|
288
|
+
}));
|
|
289
|
+
if (!status.running) {
|
|
290
|
+
if (status.error)
|
|
291
|
+
throw new Error(status.error);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
sleep(ms) {
|
|
297
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
298
|
+
}
|
|
299
|
+
async fetchRemoteEvents(scope, afterIndex, syncMode = false) {
|
|
300
|
+
const url = this.remoteEventsUrl(scope, afterIndex, syncMode);
|
|
301
|
+
let response = await this.fetchWithTimeout(url);
|
|
302
|
+
if (!response.ok && syncMode) {
|
|
303
|
+
response = await this.fetchWithTimeout(this.remoteEventsUrl(scope, afterIndex, false));
|
|
304
|
+
}
|
|
305
|
+
if (!response.ok) {
|
|
306
|
+
throw new Error(`Failed to fetch events: ${response.statusText}`);
|
|
307
|
+
}
|
|
308
|
+
const data = (await response.json());
|
|
309
|
+
return {
|
|
310
|
+
events: data.events.map(chainEventFromWire),
|
|
311
|
+
syncStatus: data.syncStatus ? syncStatusFromWire(data.syncStatus) : null,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
remoteEventsUrl(scope, afterIndex, syncMode = false) {
|
|
143
315
|
const params = new URLSearchParams();
|
|
144
316
|
if (afterIndex !== null && afterIndex !== undefined) {
|
|
145
317
|
params.set("after_index", afterIndex.toString());
|
|
146
318
|
}
|
|
319
|
+
if (syncMode) {
|
|
320
|
+
params.set("sync", syncMode);
|
|
321
|
+
}
|
|
147
322
|
const query = params.toString();
|
|
148
|
-
|
|
149
|
-
(query ? `?${query}` : "");
|
|
323
|
+
return (`${this.baseUrl}/api/events/${scope.scopeType}/${scope.scopeKey}` +
|
|
324
|
+
(query ? `?${query}` : ""));
|
|
325
|
+
}
|
|
326
|
+
fetchWithTimeout(url) {
|
|
327
|
+
return fetch(url, {
|
|
328
|
+
method: "GET",
|
|
329
|
+
signal: AbortSignal.timeout(this.timeout),
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
async fetchRemoteSyncStatus(scope) {
|
|
333
|
+
const url = `${this.baseUrl}/api/sync/${scope.scopeType}/${scope.scopeKey}/status`;
|
|
150
334
|
const response = await fetch(url, {
|
|
151
335
|
method: "GET",
|
|
152
336
|
signal: AbortSignal.timeout(this.timeout),
|
|
153
337
|
});
|
|
154
338
|
if (!response.ok) {
|
|
155
|
-
throw new Error(`Failed to fetch
|
|
339
|
+
throw new Error(`Failed to fetch sync status: ${response.statusText}`);
|
|
156
340
|
}
|
|
157
|
-
|
|
158
|
-
return data.events.map(chainEventFromWire);
|
|
341
|
+
return syncStatusFromWire((await response.json()));
|
|
159
342
|
}
|
|
160
343
|
}
|
|
344
|
+
function cursorFromWire(cursor) {
|
|
345
|
+
if (!cursor)
|
|
346
|
+
return null;
|
|
347
|
+
return {
|
|
348
|
+
scopeType: cursor.scopeType,
|
|
349
|
+
scopeKey: cursor.scopeKey,
|
|
350
|
+
lastIndex: cursor.lastIndex === null ? null : BigInt(cursor.lastIndex),
|
|
351
|
+
lastSignature: cursor.lastSignature,
|
|
352
|
+
lastSyncAt: cursor.lastSyncAt,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function syncStatusFromWire(status) {
|
|
356
|
+
return {
|
|
357
|
+
...status,
|
|
358
|
+
cursor: cursorFromWire(status.cursor),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
161
361
|
export function createSubstreamRuntime(ctx, stores, config, modules) {
|
|
162
362
|
return new SubstreamRuntime(ctx, stores, config, modules);
|
|
163
363
|
}
|
|
@@ -31,6 +31,7 @@ export class HttpServer {
|
|
|
31
31
|
setupRoutes() {
|
|
32
32
|
this.app.get("/health", this.handleHealth.bind(this));
|
|
33
33
|
this.app.get("/api/events/:scopeType/:scopeKey", this.handleGetEvents.bind(this));
|
|
34
|
+
this.app.get("/api/sync/:scopeType/:scopeKey/status", this.handleGetSyncStatus.bind(this));
|
|
34
35
|
this.app.use((_req, res) => {
|
|
35
36
|
res.status(404).json({ error: "Not found" });
|
|
36
37
|
});
|
|
@@ -53,19 +54,19 @@ export class HttpServer {
|
|
|
53
54
|
const afterIndex = this.parseAfterIndex(req, res);
|
|
54
55
|
if (afterIndex === false)
|
|
55
56
|
return;
|
|
56
|
-
|
|
57
|
+
const syncMode = req.query.sync;
|
|
58
|
+
const syncStatus = syncMode === "skip"
|
|
59
|
+
? this.runtime.getSyncStatus(scope, "local")
|
|
60
|
+
: syncMode === "background"
|
|
61
|
+
? this.runtime.syncLocalInBackground(scope)
|
|
62
|
+
: await this.syncAndGetStatus(scope);
|
|
57
63
|
const events = await this.runtime.events.getAfter(scope, afterIndex === null ? undefined : afterIndex);
|
|
58
64
|
const cursor = await this.runtime.events.getCursor(scope);
|
|
59
65
|
res.json({
|
|
60
66
|
events: events.map(chainEventToWire),
|
|
61
67
|
total: events.length,
|
|
62
|
-
cursor: cursor
|
|
63
|
-
|
|
64
|
-
lastIndex: cursor.lastIndex === null ? null : cursor.lastIndex.toString(),
|
|
65
|
-
lastSignature: cursor.lastSignature,
|
|
66
|
-
lastSyncAt: cursor.lastSyncAt,
|
|
67
|
-
}
|
|
68
|
-
: null,
|
|
68
|
+
cursor: cursorToWire(cursor),
|
|
69
|
+
syncStatus: syncStatusToWire(syncStatus),
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
catch (error) {
|
|
@@ -73,6 +74,22 @@ export class HttpServer {
|
|
|
73
74
|
res.status(500).json({ error: "Failed to fetch events" });
|
|
74
75
|
}
|
|
75
76
|
}
|
|
77
|
+
async handleGetSyncStatus(req, res) {
|
|
78
|
+
try {
|
|
79
|
+
const scope = this.parseScope(req, res);
|
|
80
|
+
if (!scope)
|
|
81
|
+
return;
|
|
82
|
+
res.json(syncStatusToWire(this.runtime.getSyncStatus(scope, "local")));
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
logger.error({ err: error, params: req.params }, "fetch sync status failed");
|
|
86
|
+
res.status(500).json({ error: "Failed to fetch sync status" });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async syncAndGetStatus(scope) {
|
|
90
|
+
await this.runtime.syncLocal(scope);
|
|
91
|
+
return this.runtime.getSyncStatus(scope, "local");
|
|
92
|
+
}
|
|
76
93
|
parseScope(req, res) {
|
|
77
94
|
const scopeType = String(req.params.scopeType);
|
|
78
95
|
const scopeKey = String(req.params.scopeKey);
|
|
@@ -138,6 +155,23 @@ export class HttpServer {
|
|
|
138
155
|
return `http://${this.host}:${this.port}`;
|
|
139
156
|
}
|
|
140
157
|
}
|
|
158
|
+
function cursorToWire(cursor) {
|
|
159
|
+
return cursor
|
|
160
|
+
? {
|
|
161
|
+
scopeType: cursor.scopeType,
|
|
162
|
+
scopeKey: cursor.scopeKey,
|
|
163
|
+
lastIndex: cursor.lastIndex === null ? null : cursor.lastIndex.toString(),
|
|
164
|
+
lastSignature: cursor.lastSignature,
|
|
165
|
+
lastSyncAt: cursor.lastSyncAt,
|
|
166
|
+
}
|
|
167
|
+
: null;
|
|
168
|
+
}
|
|
169
|
+
function syncStatusToWire(status) {
|
|
170
|
+
return {
|
|
171
|
+
...status,
|
|
172
|
+
cursor: cursorToWire(status.cursor),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
141
175
|
export class SubstreamService {
|
|
142
176
|
ctx;
|
|
143
177
|
options;
|
|
@@ -44,6 +44,26 @@ export interface EventCursor {
|
|
|
44
44
|
lastSignature: string | null;
|
|
45
45
|
lastSyncAt: number;
|
|
46
46
|
}
|
|
47
|
+
export interface SyncProgress {
|
|
48
|
+
current: number;
|
|
49
|
+
total: number;
|
|
50
|
+
signature: string;
|
|
51
|
+
}
|
|
52
|
+
export type SyncPhase = "idle" | "checking" | "syncing" | "complete" | "failed";
|
|
53
|
+
export interface SyncStatus extends EventScope {
|
|
54
|
+
mode: "local" | "remote";
|
|
55
|
+
phase: SyncPhase;
|
|
56
|
+
running: boolean;
|
|
57
|
+
progress: SyncProgress | null;
|
|
58
|
+
cursor: EventCursor | null;
|
|
59
|
+
error: string | null;
|
|
60
|
+
startedAt: number | null;
|
|
61
|
+
updatedAt: number;
|
|
62
|
+
completedAt: number | null;
|
|
63
|
+
}
|
|
64
|
+
export interface SyncStatusReporter {
|
|
65
|
+
update(status: SyncStatus): void;
|
|
66
|
+
}
|
|
47
67
|
export type ApplyOutcome = {
|
|
48
68
|
kind: "applied";
|
|
49
69
|
cursor: bigint;
|
|
@@ -84,6 +104,7 @@ export interface ProjectionStore {
|
|
|
84
104
|
initialize(): Promise<void>;
|
|
85
105
|
get(projectionId: string, key: string): Promise<ProjectionStateRecord | null>;
|
|
86
106
|
put(record: ProjectionStateRecord): Promise<void>;
|
|
107
|
+
delete(projectionId: string, key: string): Promise<void>;
|
|
87
108
|
list(projectionId: string): Promise<ProjectionStateRecord[]>;
|
|
88
109
|
clear(projectionId: string): Promise<void>;
|
|
89
110
|
}
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { TransactionInstruction } from "@solana/web3.js";
|
|
2
2
|
import { Context } from "../context.js";
|
|
3
3
|
import type { DepositRecord } from "../substream/types.js";
|
|
4
|
+
import type { ChainSyncOptions } from "../substream/chain/index.js";
|
|
4
5
|
export declare function depositIx(ctx: Context, commitment: string, denomination: bigint): Promise<TransactionInstruction[]>;
|
|
5
6
|
export declare const deposit: <S extends boolean = true>(ctx: Context, commitment: string, denomination: bigint, sign?: S | undefined) => Promise<import("../index.js").SignReturn<S>>;
|
|
6
7
|
export declare function listDeposits(ctx: Context, denomination: bigint, options?: {
|
|
7
8
|
offset?: number;
|
|
8
9
|
limit?: number;
|
|
9
10
|
output?: string;
|
|
11
|
+
sync?: ChainSyncOptions;
|
|
10
12
|
}): Promise<DepositRecord[]>;
|
package/dist/voidify/deposit.js
CHANGED
|
@@ -26,7 +26,7 @@ export async function listDeposits(ctx, denomination, options) {
|
|
|
26
26
|
const client = new SubstreamCliClient(ctx);
|
|
27
27
|
await client.init();
|
|
28
28
|
const depositModule = client.module("deposit");
|
|
29
|
-
await depositModule.sync(denomination);
|
|
29
|
+
await depositModule.sync(denomination, options?.sync);
|
|
30
30
|
const deposits = await depositModule.list(denomination, {
|
|
31
31
|
offset: options?.offset,
|
|
32
32
|
limit: options?.limit,
|
|
@@ -6,7 +6,6 @@ export declare class VoidifyProgram {
|
|
|
6
6
|
private _program;
|
|
7
7
|
private _programId;
|
|
8
8
|
static readonly SEEDS: {
|
|
9
|
-
readonly CORE_CONFIG: Buffer<ArrayBufferLike>;
|
|
10
9
|
readonly STAKE_CONFIG: Buffer<ArrayBufferLike>;
|
|
11
10
|
readonly TREASURY_CONFIG: Buffer<ArrayBufferLike>;
|
|
12
11
|
readonly ORACLE_CONFIG: Buffer<ArrayBufferLike>;
|
|
@@ -17,12 +16,10 @@ export declare class VoidifyProgram {
|
|
|
17
16
|
readonly RELAYER_CONFIG: Buffer<ArrayBufferLike>;
|
|
18
17
|
readonly RELAYER_EVENT_COUNTER: Buffer<ArrayBufferLike>;
|
|
19
18
|
};
|
|
20
|
-
static readonly BPF_LOADER_UPGRADEABLE_PROGRAM_ID: PublicKey;
|
|
21
19
|
constructor(connection: Connection, programId: PublicKey);
|
|
22
20
|
get program(): Program<Voidify>;
|
|
23
21
|
get programId(): PublicKey;
|
|
24
22
|
get rpcConnection(): Connection;
|
|
25
|
-
coreConfig(): PublicKey;
|
|
26
23
|
stakeConfig(): PublicKey;
|
|
27
24
|
treasuryConfig(): PublicKey;
|
|
28
25
|
oracleConfig(): PublicKey;
|
|
@@ -32,5 +29,4 @@ export declare class VoidifyProgram {
|
|
|
32
29
|
nullifier(nullifierHash: Uint8Array): PublicKey;
|
|
33
30
|
relayerConfig(relayerPubkey: PublicKey): PublicKey;
|
|
34
31
|
relayerEventCounter(): PublicKey;
|
|
35
|
-
programData(): PublicKey;
|
|
36
32
|
}
|
package/dist/voidify/program.js
CHANGED
|
@@ -7,7 +7,6 @@ export class VoidifyProgram {
|
|
|
7
7
|
_program = null;
|
|
8
8
|
_programId;
|
|
9
9
|
static SEEDS = {
|
|
10
|
-
CORE_CONFIG: getConstSeed(idl, "core_config"),
|
|
11
10
|
STAKE_CONFIG: getConstSeed(idl, "stake_config"),
|
|
12
11
|
TREASURY_CONFIG: getConstSeed(idl, "treasury_config"),
|
|
13
12
|
ORACLE_CONFIG: getConstSeed(idl, "oracle_config"),
|
|
@@ -18,7 +17,6 @@ export class VoidifyProgram {
|
|
|
18
17
|
RELAYER_CONFIG: getConstSeed(idl, "relayer_config"),
|
|
19
18
|
RELAYER_EVENT_COUNTER: getConstSeed(idl, "relayer_event_counter"),
|
|
20
19
|
};
|
|
21
|
-
static BPF_LOADER_UPGRADEABLE_PROGRAM_ID = new PublicKey("BPFLoaderUpgradeab1e11111111111111111111111");
|
|
22
20
|
constructor(connection, programId) {
|
|
23
21
|
this.connection = connection;
|
|
24
22
|
this._programId = programId;
|
|
@@ -38,10 +36,6 @@ export class VoidifyProgram {
|
|
|
38
36
|
get rpcConnection() {
|
|
39
37
|
return this.connection;
|
|
40
38
|
}
|
|
41
|
-
coreConfig() {
|
|
42
|
-
const [pda] = PublicKey.findProgramAddressSync([VoidifyProgram.SEEDS.CORE_CONFIG], this._programId);
|
|
43
|
-
return pda;
|
|
44
|
-
}
|
|
45
39
|
stakeConfig() {
|
|
46
40
|
const [pda] = PublicKey.findProgramAddressSync([VoidifyProgram.SEEDS.STAKE_CONFIG], this._programId);
|
|
47
41
|
return pda;
|
|
@@ -80,8 +74,4 @@ export class VoidifyProgram {
|
|
|
80
74
|
const [pda] = PublicKey.findProgramAddressSync([VoidifyProgram.SEEDS.RELAYER_EVENT_COUNTER], this._programId);
|
|
81
75
|
return pda;
|
|
82
76
|
}
|
|
83
|
-
programData() {
|
|
84
|
-
const [pda] = PublicKey.findProgramAddressSync([this._programId.toBuffer()], VoidifyProgram.BPF_LOADER_UPGRADEABLE_PROGRAM_ID);
|
|
85
|
-
return pda;
|
|
86
|
-
}
|
|
87
77
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Context } from "../../context.js";
|
|
2
2
|
import type { RelayerRecord } from "../../substream/types.js";
|
|
3
|
+
import type { ChainSyncOptions } from "../../substream/chain/index.js";
|
|
3
4
|
export declare function listRelayers(ctx: Context, pubkey?: string, options?: {
|
|
4
5
|
output?: string;
|
|
6
|
+
sync?: ChainSyncOptions;
|
|
5
7
|
}): Promise<RelayerRecord[] | RelayerRecord | null>;
|
|
@@ -3,7 +3,7 @@ export async function listRelayers(ctx, pubkey, options) {
|
|
|
3
3
|
const client = new SubstreamCliClient(ctx);
|
|
4
4
|
await client.init();
|
|
5
5
|
const relayerModule = client.module("relayer");
|
|
6
|
-
await relayerModule.sync();
|
|
6
|
+
await relayerModule.sync(options?.sync);
|
|
7
7
|
const result = pubkey
|
|
8
8
|
? await relayerModule.get(pubkey)
|
|
9
9
|
: await relayerModule.list();
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
2
2
|
import { Context } from "../context.js";
|
|
3
3
|
import { Note } from "../utils/note.js";
|
|
4
|
+
import type { ChainSyncOptions } from "../substream/chain/index.js";
|
|
4
5
|
export declare function directWithdrawIx(ctx: Context, proof: Uint8Array, root: Uint8Array, nullifierHash: Uint8Array, recipient: string, fee: bigint, treasury: bigint, denomination: bigint): Promise<TransactionInstruction[]>;
|
|
5
6
|
export declare function withdrawIx(ctx: Context, proof: Uint8Array, root: Uint8Array, nullifierHash: Uint8Array, recipient: string, relayer: string, fee: bigint, treasury: bigint, switchboardQuote: PublicKey, denomination: bigint): Promise<TransactionInstruction[]>;
|
|
6
7
|
export interface WithdrawArtifact {
|
|
7
8
|
withdrawData: string;
|
|
8
9
|
relayerUrl: string;
|
|
9
10
|
}
|
|
11
|
+
export interface WithdrawSyncOptions {
|
|
12
|
+
depositSync?: ChainSyncOptions;
|
|
13
|
+
relayerSync?: ChainSyncOptions;
|
|
14
|
+
}
|
|
10
15
|
export declare function validateNote(ctx: Context, note_str: string): Promise<{
|
|
11
16
|
note: Note;
|
|
12
17
|
}>;
|
|
13
|
-
export declare function prepareWithdraw(ctx: Context, note_str: string, recipient
|
|
18
|
+
export declare function prepareWithdraw(ctx: Context, note_str: string, recipient?: string, relayerName?: string, options?: WithdrawSyncOptions, sendRpc?: boolean): Promise<WithdrawArtifact>;
|
|
14
19
|
export declare function submitWithdrawToRelayer(artifact: WithdrawArtifact): Promise<string>;
|
|
15
|
-
export declare function withdraw(ctx: Context, note_str: string, recipient
|
|
20
|
+
export declare function withdraw(ctx: Context, note_str: string, recipient?: string, relayerName?: string, options?: WithdrawSyncOptions, sendRpc?: boolean): Promise<string>;
|
|
16
21
|
export declare function directWithdraw(ctx: Context, note_str: string, recipient: string): Promise<string>;
|