@silvana-one/mina-prover 0.2.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 (62) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1 -0
  3. package/dist/node/api/api.d.ts +211 -0
  4. package/dist/node/api/api.js +472 -0
  5. package/dist/node/api/api.js.map +1 -0
  6. package/dist/node/index.cjs +1161 -0
  7. package/dist/node/index.d.ts +4 -0
  8. package/dist/node/index.js +5 -0
  9. package/dist/node/index.js.map +1 -0
  10. package/dist/node/local/local.d.ts +292 -0
  11. package/dist/node/local/local.js +528 -0
  12. package/dist/node/local/local.js.map +1 -0
  13. package/dist/node/tokens/index.d.ts +2 -0
  14. package/dist/node/tokens/index.js +3 -0
  15. package/dist/node/tokens/index.js.map +1 -0
  16. package/dist/node/tokens/nft.d.ts +29 -0
  17. package/dist/node/tokens/nft.js +107 -0
  18. package/dist/node/tokens/nft.js.map +1 -0
  19. package/dist/node/tokens/token.d.ts +29 -0
  20. package/dist/node/tokens/token.js +99 -0
  21. package/dist/node/tokens/token.js.map +1 -0
  22. package/dist/node/verification/index.d.ts +1 -0
  23. package/dist/node/verification/index.js +2 -0
  24. package/dist/node/verification/index.js.map +1 -0
  25. package/dist/node/verification/verification.d.ts +21 -0
  26. package/dist/node/verification/verification.js +2 -0
  27. package/dist/node/verification/verification.js.map +1 -0
  28. package/dist/tsconfig.tsbuildinfo +1 -0
  29. package/dist/tsconfig.web.tsbuildinfo +1 -0
  30. package/dist/web/api/api.d.ts +211 -0
  31. package/dist/web/api/api.js +472 -0
  32. package/dist/web/api/api.js.map +1 -0
  33. package/dist/web/index.d.ts +4 -0
  34. package/dist/web/index.js +5 -0
  35. package/dist/web/index.js.map +1 -0
  36. package/dist/web/local/local.d.ts +292 -0
  37. package/dist/web/local/local.js +528 -0
  38. package/dist/web/local/local.js.map +1 -0
  39. package/dist/web/tokens/index.d.ts +2 -0
  40. package/dist/web/tokens/index.js +3 -0
  41. package/dist/web/tokens/index.js.map +1 -0
  42. package/dist/web/tokens/nft.d.ts +29 -0
  43. package/dist/web/tokens/nft.js +107 -0
  44. package/dist/web/tokens/nft.js.map +1 -0
  45. package/dist/web/tokens/token.d.ts +29 -0
  46. package/dist/web/tokens/token.js +99 -0
  47. package/dist/web/tokens/token.js.map +1 -0
  48. package/dist/web/verification/index.d.ts +1 -0
  49. package/dist/web/verification/index.js +2 -0
  50. package/dist/web/verification/index.js.map +1 -0
  51. package/dist/web/verification/verification.d.ts +21 -0
  52. package/dist/web/verification/verification.js +2 -0
  53. package/dist/web/verification/verification.js.map +1 -0
  54. package/package.json +68 -0
  55. package/src/api/api.ts +613 -0
  56. package/src/index.ts +4 -0
  57. package/src/local/local.ts +651 -0
  58. package/src/tokens/index.ts +2 -0
  59. package/src/tokens/nft.ts +147 -0
  60. package/src/tokens/token.ts +140 -0
  61. package/src/verification/index.ts +1 -0
  62. package/src/verification/verification.ts +23 -0
@@ -0,0 +1,651 @@
1
+ import {
2
+ CloudTransaction,
3
+ DeployerKeyPair,
4
+ Cloud,
5
+ JobData,
6
+ JobEvent,
7
+ TaskData,
8
+ zkCloudWorker,
9
+ TransactionMetadata,
10
+ blockchain,
11
+ Local,
12
+ } from "@silvana-one/prover";
13
+ import { makeString } from "@silvana-one/mina-utils";
14
+ import { ApiCommand } from "../api/api.js";
15
+
16
+ /**
17
+ * LocalCloud is a cloud that runs on the local machine for testing and development
18
+ * It uses LocalStorage to store jobs, tasks, transactions, and data
19
+ * It uses a localWorker to execute the tasks
20
+ * It can be used to test the cloud functionality without deploying to the cloud
21
+ * @param localWorker the worker to execute the tasks
22
+ */
23
+ export class LocalCloud extends Cloud {
24
+ readonly localWorker: (cloud: Cloud) => Promise<zkCloudWorker>;
25
+
26
+ /**
27
+ * Constructor for LocalCloud
28
+ * @param params the parameters to create the LocalCloud
29
+ * @param params.job the job data
30
+ * @param params.chain the blockchain to execute the job on, can be any blockchain, not only local
31
+ * @param params.cache the cache folder
32
+ * @param params.stepId the step id
33
+ * @param params.localWorker the worker to execute the tasks
34
+ */
35
+ constructor(params: {
36
+ job: JobData;
37
+ chain: blockchain;
38
+ cache?: string;
39
+ stepId?: string;
40
+ localWorker: (cloud: Cloud) => Promise<zkCloudWorker>;
41
+ }) {
42
+ const { job, chain, cache, stepId, localWorker } = params;
43
+
44
+ const { id, jobId, developer, repo, task, userId, args, metadata, taskId } =
45
+ job;
46
+ super({
47
+ id: id,
48
+ jobId: jobId,
49
+ stepId: stepId ?? "stepId",
50
+ taskId: taskId ?? "taskId",
51
+ cache: cache ?? "./cache",
52
+ developer: developer,
53
+ repo: repo,
54
+ task: task,
55
+ userId: userId,
56
+ args: args,
57
+ metadata: metadata,
58
+ isLocalCloud: true,
59
+ chain,
60
+ });
61
+ this.localWorker = localWorker;
62
+ }
63
+
64
+ /**
65
+ * Provides the deployer key pair for testing and development
66
+ * @returns the deployer key pair
67
+ */
68
+ public async getDeployer(): Promise<DeployerKeyPair | undefined> {
69
+ const privateKey = process.env.DEPLOYER_PRIVATE_KEY;
70
+ const publicKey = process.env.DEPLOYER_PUBLIC_KEY;
71
+ try {
72
+ return privateKey === undefined || publicKey === undefined
73
+ ? undefined
74
+ : ({
75
+ privateKey,
76
+ publicKey,
77
+ } as DeployerKeyPair);
78
+ } catch (error) {
79
+ console.error(
80
+ `getDeployer: error getting deployer key pair: ${error}`,
81
+ error
82
+ );
83
+ return undefined;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Releases the deployer key pair
89
+ */
90
+ public async releaseDeployer(params: {
91
+ publicKey: string;
92
+ txsHashes: string[];
93
+ }): Promise<void> {
94
+ console.log("LocalCloud: releaseDeployer", params);
95
+ }
96
+
97
+ /**
98
+ * Gets the data by key
99
+ * @param key the key to get the data
100
+ * @returns the data
101
+ */
102
+ public async getDataByKey(key: string): Promise<string | undefined> {
103
+ const value = LocalStorage.data[key];
104
+ return value;
105
+ }
106
+
107
+ /**
108
+ * Saves the data by key
109
+ * @param key the key to save the data
110
+ * @param value the value to save
111
+ */
112
+ public async saveDataByKey(
113
+ key: string,
114
+ value: string | undefined
115
+ ): Promise<void> {
116
+ if (value !== undefined) LocalStorage.data[key] = value;
117
+ else delete LocalStorage.data[key];
118
+ }
119
+
120
+ /**
121
+ * Saves the file
122
+ * @param filename the filename to save
123
+ * @param value the value to save
124
+ */
125
+ public async saveFile(filename: string, value: Buffer): Promise<void> {
126
+ LocalStorage.files[filename] = value;
127
+ //throw new Error("Method not implemented.");
128
+ //await saveBinaryFile({ data: value, filename });
129
+ }
130
+
131
+ /**
132
+ * Loads the file
133
+ * @param filename
134
+ * @returns the file data
135
+ */
136
+ public async loadFile(filename: string): Promise<Buffer | undefined> {
137
+ return LocalStorage.files[filename];
138
+ //throw new Error("Method not implemented.");
139
+ //const data = await loadBinaryFile(filename);
140
+ //return data;
141
+ }
142
+
143
+ /**
144
+ * Encrypts the data
145
+ * @param params
146
+ * @param params.data the data
147
+ * @param params.context the context
148
+ * @param params.keyId the key id, optional
149
+ * @returns encrypted data
150
+ */
151
+ public async encrypt(params: {
152
+ data: string;
153
+ context: string;
154
+ keyId?: string;
155
+ }): Promise<string | undefined> {
156
+ return JSON.stringify(params);
157
+ }
158
+
159
+ /**
160
+ * Decrypts the data
161
+ * @param params
162
+ * @param params.data the data
163
+ * @param params.context the context
164
+ * @param params.keyId the key id, optional
165
+ * @returns
166
+ */
167
+ public async decrypt(params: {
168
+ data: string;
169
+ context: string;
170
+ keyId?: string;
171
+ }): Promise<string | undefined> {
172
+ const { data, context, keyId } = JSON.parse(params.data);
173
+ if (context !== params.context) {
174
+ console.error("decrypt: context mismatch");
175
+ return undefined;
176
+ }
177
+ if (keyId !== params.keyId) {
178
+ console.error("decrypt: keyId mismatch");
179
+ return undefined;
180
+ }
181
+ return data;
182
+ }
183
+
184
+ /**
185
+ * Generates an id for local cloud
186
+ * @returns generated unique id
187
+ */
188
+ private static generateId(tx: string | undefined = undefined): string {
189
+ //const data =
190
+ // tx ?? JSON.stringify({ time: Date.now(), data: makeString(32) });
191
+ //return stringHash(data);
192
+ return Date.now() + "." + makeString(32);
193
+ }
194
+
195
+ /**
196
+ * Send transactions to the local cloud
197
+ * @param transactions the transactions to add
198
+ * @returns the transaction ids
199
+ */
200
+ public async sendTransactions(
201
+ transactions: string[]
202
+ ): Promise<CloudTransaction[]> {
203
+ return await LocalCloud.addTransactions(transactions);
204
+ }
205
+
206
+ /**
207
+ * Adds transactions to the local cloud
208
+ * @param transactions the transactions to add
209
+ * @returns the transaction ids
210
+ */
211
+ public static async addTransactions(
212
+ transactions: string[] | CloudTransaction[]
213
+ ): Promise<CloudTransaction[]> {
214
+ const timeReceived = Date.now();
215
+ const txs: CloudTransaction[] = [];
216
+ transactions.forEach((tx) => {
217
+ if (typeof tx === "string") {
218
+ const txId = LocalCloud.generateId(
219
+ JSON.stringify({ tx, time: timeReceived })
220
+ );
221
+ const transaction: CloudTransaction = {
222
+ txId,
223
+ transaction: tx,
224
+ timeReceived,
225
+ status: "accepted",
226
+ };
227
+ LocalStorage.transactions[txId] = transaction;
228
+ txs.push(transaction);
229
+ } else {
230
+ LocalStorage.transactions[tx.txId] = tx;
231
+ txs.push(tx);
232
+ }
233
+ });
234
+ return txs;
235
+ }
236
+
237
+ /**
238
+ * Deletes a transaction from the local cloud
239
+ * @param txId the transaction id to delete
240
+ */
241
+ public async deleteTransaction(txId: string): Promise<void> {
242
+ if (LocalStorage.transactions[txId] === undefined)
243
+ throw new Error(`deleteTransaction: Transaction ${txId} not found`);
244
+ delete LocalStorage.transactions[txId];
245
+ }
246
+
247
+ public async getTransactions(): Promise<CloudTransaction[]> {
248
+ const txs = Object.keys(LocalStorage.transactions).map((txId) => {
249
+ return LocalStorage.transactions[txId];
250
+ });
251
+ return txs;
252
+ }
253
+
254
+ /**
255
+ * Publish the transaction metadata in human-readable format
256
+ * @param params
257
+ * @param params.txId the transaction id
258
+ * @param params.metadata the metadata
259
+ */
260
+ public async publishTransactionMetadata(params: {
261
+ txId: string;
262
+ metadata: TransactionMetadata;
263
+ }): Promise<void> {
264
+ console.log("publishTransactionMetadata:", params);
265
+ }
266
+
267
+ /**
268
+ * Runs the worker in the local cloud
269
+ * @param params the parameters to run the worker
270
+ * @param params.command the command to run
271
+ * @param params.data the data to use
272
+ * @param params.chain the blockchain to execute the job on
273
+ * @param params.localWorker the worker to execute the tasks
274
+ * @returns the job id
275
+ */
276
+ public static async run(params: {
277
+ command: ApiCommand;
278
+ data: {
279
+ developer: string;
280
+ repo: string;
281
+ transactions: string[];
282
+ task: string;
283
+ userId?: string;
284
+ args?: string;
285
+ metadata?: string;
286
+ };
287
+ chain: blockchain;
288
+ localWorker: (cloud: Cloud) => Promise<zkCloudWorker>;
289
+ }): Promise<string> {
290
+ const { command, data, chain, localWorker } = params;
291
+ const { developer, repo, transactions, task, userId, args, metadata } =
292
+ data;
293
+
294
+ const timeCreated = Date.now();
295
+ const jobId = LocalCloud.generateId();
296
+ const job: JobData = {
297
+ id: "local",
298
+ jobId,
299
+ developer,
300
+ repo,
301
+ task,
302
+ userId,
303
+ args,
304
+ metadata,
305
+ txNumber: command === "recursiveProof" ? transactions.length : 1,
306
+ timeCreated,
307
+ timeStarted: timeCreated,
308
+ chain,
309
+ } as JobData;
310
+ const cloud = new LocalCloud({
311
+ job,
312
+ chain,
313
+ localWorker,
314
+ });
315
+ const worker = await localWorker(cloud);
316
+ if (worker === undefined) throw new Error("worker is undefined");
317
+ const result =
318
+ command === "recursiveProof"
319
+ ? await LocalCloud.sequencer({
320
+ worker,
321
+ data,
322
+ })
323
+ : command === "execute"
324
+ ? await worker.execute(transactions)
325
+ : undefined;
326
+
327
+ const timeFinished = Date.now();
328
+ if (result !== undefined) {
329
+ LocalStorage.jobEvents[jobId] = {
330
+ jobId,
331
+ jobStatus: "finished",
332
+ eventTime: timeFinished,
333
+ result,
334
+ };
335
+ job.timeFinished = timeFinished;
336
+ job.jobStatus = "finished";
337
+ job.result = result;
338
+ } else {
339
+ LocalStorage.jobEvents[jobId] = {
340
+ jobId,
341
+ jobStatus: "failed",
342
+ eventTime: timeFinished,
343
+ };
344
+ job.timeFailed = timeFinished;
345
+ job.jobStatus = "failed";
346
+ }
347
+ job.billedDuration = timeFinished - timeCreated;
348
+ LocalStorage.jobs[jobId] = job;
349
+ return jobId;
350
+ }
351
+
352
+ /**
353
+ * Runs the recursive proof in the local cloud
354
+ * @param data the data to use
355
+ * @param data.transactions the transactions to process
356
+ * @param data.task the task to execute
357
+ * @param data.userId the user id
358
+ * @param data.args the arguments for the job
359
+ * @param data.metadata the metadata for the job
360
+ * @returns the job id
361
+ */
362
+ public async recursiveProof(data: {
363
+ transactions: string[];
364
+ task?: string;
365
+ userId?: string;
366
+ args?: string;
367
+ metadata?: string;
368
+ }): Promise<string> {
369
+ return await LocalCloud.run({
370
+ command: "recursiveProof",
371
+ data: {
372
+ developer: this.developer,
373
+ repo: this.repo,
374
+ transactions: data.transactions,
375
+ task: data.task ?? "recursiveProof",
376
+ userId: data.userId,
377
+ args: data.args,
378
+ metadata: data.metadata,
379
+ },
380
+ chain: this.chain,
381
+ localWorker: this.localWorker,
382
+ });
383
+ }
384
+
385
+ /**
386
+ * Executes the task in the local cloud
387
+ * @param data the data to use
388
+ * @param data.transactions the transactions to process
389
+ * @param data.task the task to execute
390
+ * @param data.userId the user id
391
+ * @param data.args the arguments for the job
392
+ * @param data.metadata the metadata for the job
393
+ * @returns the job id
394
+ */
395
+ public async execute(data: {
396
+ transactions: string[];
397
+ task: string;
398
+ userId?: string;
399
+ args?: string;
400
+ metadata?: string;
401
+ }): Promise<string> {
402
+ return await LocalCloud.run({
403
+ command: "execute",
404
+ data: {
405
+ developer: this.developer,
406
+ repo: this.repo,
407
+ transactions: data.transactions,
408
+ task: data.task,
409
+ userId: data.userId,
410
+ args: data.args,
411
+ metadata: data.metadata,
412
+ },
413
+ chain: this.chain,
414
+ localWorker: this.localWorker,
415
+ });
416
+ }
417
+
418
+ /**
419
+ * Gets the job result
420
+ * @param jobId the job id
421
+ * @returns the job data
422
+ */
423
+ public async jobResult(jobId: string): Promise<JobData | undefined> {
424
+ return LocalStorage.jobs[jobId];
425
+ }
426
+
427
+ /**
428
+ * Adds a task to the local cloud
429
+ * @param data the data to use
430
+ * @param data.task the task to execute
431
+ * @param data.startTime the start time for the task
432
+ * @param data.userId the user id
433
+ * @param data.args the arguments for the job
434
+ * @param data.metadata the metadata for the job
435
+ * @returns the task id
436
+ */
437
+ public async addTask(data: {
438
+ task: string;
439
+ startTime?: number;
440
+ userId?: string;
441
+ args?: string;
442
+ metadata?: string;
443
+ }): Promise<string> {
444
+ const taskId = LocalCloud.generateId();
445
+ LocalStorage.tasks[taskId] = {
446
+ ...data,
447
+ id: "local",
448
+ taskId,
449
+ timeCreated: Date.now(),
450
+ developer: this.developer,
451
+ repo: this.repo,
452
+ chain: this.chain,
453
+ } as TaskData;
454
+ return taskId;
455
+ }
456
+
457
+ /**
458
+ * Deletes a task from the local cloud
459
+ * @param taskId the task id to delete
460
+ */
461
+ public async deleteTask(taskId: string): Promise<void> {
462
+ if (LocalStorage.tasks[taskId] === undefined)
463
+ throw new Error(`deleteTask: Task ${taskId} not found`);
464
+ delete LocalStorage.tasks[taskId];
465
+ }
466
+
467
+ /**
468
+ * Processes the tasks in the local cloud
469
+ */
470
+ public async processTasks(): Promise<void> {
471
+ await LocalCloud.processLocalTasks({
472
+ developer: this.developer,
473
+ repo: this.repo,
474
+ localWorker: this.localWorker,
475
+ chain: this.chain,
476
+ });
477
+ }
478
+
479
+ /**
480
+ * Processes the local tasks
481
+ * @param params the parameters to process the local tasks
482
+ * @param params.developer the developer of the repo
483
+ * @param params.repo the repo
484
+ * @param params.localWorker the worker to execute the tasks
485
+ * @param params.chain the blockchain to execute the job on
486
+ */
487
+ static async processLocalTasks(params: {
488
+ developer: string;
489
+ repo: string;
490
+ localWorker: (cloud: Cloud) => Promise<zkCloudWorker>;
491
+ chain: blockchain;
492
+ }): Promise<number> {
493
+ const { developer, repo, localWorker, chain } = params;
494
+ for (const taskId in LocalStorage.tasks) {
495
+ const data = LocalStorage.tasks[taskId];
496
+ const jobId = LocalCloud.generateId();
497
+ const timeCreated = Date.now();
498
+ if (data.startTime !== undefined && data.startTime < timeCreated)
499
+ continue;
500
+ const job = {
501
+ id: "local",
502
+ jobId: jobId,
503
+ taskId: taskId,
504
+ developer,
505
+ repo,
506
+ task: data.task,
507
+ userId: data.userId,
508
+ args: data.args,
509
+ metadata: data.metadata,
510
+ txNumber: 1,
511
+ timeCreated: timeCreated,
512
+ } as JobData;
513
+ const cloud = new LocalCloud({
514
+ job,
515
+ chain,
516
+ localWorker,
517
+ });
518
+ const worker = await localWorker(cloud);
519
+ const result = await worker.task();
520
+ const timeFinished = Date.now();
521
+ if (result !== undefined) {
522
+ LocalStorage.jobEvents[jobId] = {
523
+ jobId,
524
+ jobStatus: "finished",
525
+ eventTime: timeFinished,
526
+ result,
527
+ };
528
+ job.timeFinished = timeFinished;
529
+ } else {
530
+ LocalStorage.jobEvents[jobId] = {
531
+ jobId,
532
+ jobStatus: "failed",
533
+ eventTime: timeFinished,
534
+ };
535
+ job.timeFailed = timeFinished;
536
+ }
537
+ job.billedDuration = timeFinished - timeCreated;
538
+ LocalStorage.jobs[jobId] = job;
539
+ }
540
+ let count = 0;
541
+ for (const task in LocalStorage.tasks) count++;
542
+ return count;
543
+ }
544
+
545
+ /**
546
+ * Runs the sequencer in the local cloud
547
+ * @param params the parameters to run the sequencer
548
+ * @param params.worker the worker to execute the tasks
549
+ * @param params.data the data to use
550
+ * @returns the proof
551
+ */
552
+ static async sequencer(params: {
553
+ worker: zkCloudWorker;
554
+ data: {
555
+ developer: string;
556
+ repo: string;
557
+ transactions: string[];
558
+ task?: string;
559
+ userId?: string;
560
+ args?: string;
561
+ metadata?: string;
562
+ };
563
+ }): Promise<string> {
564
+ const { worker, data } = params;
565
+ const { transactions } = data;
566
+ if (transactions.length === 0)
567
+ throw new Error("No transactions to process");
568
+ const proofs: string[] = [];
569
+ for (const transaction of transactions) {
570
+ const result = await worker.create(transaction);
571
+ if (result === undefined) throw new Error("Failed to create proof");
572
+ proofs.push(result);
573
+ }
574
+ let proof = proofs[0];
575
+ for (let i = 1; i < proofs.length; i++) {
576
+ const result = await worker.merge(proof, proofs[i]);
577
+ if (result === undefined) throw new Error("Failed to merge proofs");
578
+ proof = result;
579
+ }
580
+ return proof;
581
+ }
582
+
583
+ /**
584
+ * forces the worker to restart
585
+ */
586
+ async forceWorkerRestart(): Promise<void> {
587
+ throw new Error("forceWorkerRestart called in LocalCloud");
588
+ }
589
+ }
590
+
591
+ /**
592
+ * LocalStorage is a local storage for the local cloud.
593
+ * It stores jobs, tasks, transactions, and data.
594
+ * It can be used to test the cloud functionality without deploying to the cloud.
595
+ */
596
+ export class LocalStorage {
597
+ /** The jobs */
598
+ static jobs: { [key: string]: JobData } = {};
599
+
600
+ /** The job events */
601
+ static jobEvents: { [key: string]: JobEvent } = {};
602
+
603
+ /** The data */
604
+ static data: { [key: string]: string } = {};
605
+
606
+ /** The files */
607
+ static files: { [key: string]: Buffer } = {};
608
+
609
+ /** The transactions */
610
+ static transactions: {
611
+ [key: string]: CloudTransaction;
612
+ } = {};
613
+
614
+ /** The tasks */
615
+ static tasks: { [key: string]: TaskData } = {};
616
+
617
+ /**
618
+ * Saves the data.
619
+ * @param name The name to save the data under.
620
+ * @throws Error Method not implemented to keep web compatibility.
621
+ */
622
+ static async saveData(name: string): Promise<void> {
623
+ throw new Error("Method not implemented to keep web compatibility.");
624
+ const data = {
625
+ jobs: LocalStorage.jobs,
626
+ data: LocalStorage.data,
627
+ transactions: LocalStorage.transactions,
628
+ tasks: LocalStorage.tasks,
629
+ };
630
+ const filename = name + ".cloud";
631
+ // await saveFile({ data, filename });
632
+ }
633
+
634
+ /**
635
+ * Loads the data.
636
+ * @param name The name to load the data from.
637
+ * @throws Error Method not implemented to keep web compatibility.
638
+ */
639
+ static async loadData(name: string): Promise<void> {
640
+ throw new Error("Method not implemented to keep web compatibility.");
641
+ const filename = name + ".cloud";
642
+ /*
643
+ const data = await loadFile(filename);
644
+ if (data === undefined) return;
645
+ LocalStorage.jobs = data.jobs;
646
+ LocalStorage.data = data.data;
647
+ LocalStorage.transactions = data.transactions;
648
+ LocalStorage.tasks = data.tasks;
649
+ */
650
+ }
651
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./token.js";
2
+ export * from "./nft.js";