@storacha/clawracha 0.1.2 → 0.1.4
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/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +33 -13
- package/dist/sync.d.ts +15 -12
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +40 -32
- package/package.json +1 -1
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAgH7B,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QA6jBpD"}
|
package/dist/plugin.js
CHANGED
|
@@ -40,8 +40,7 @@ async function startWorkspaceSync(workspace, agentId, pluginConfig, logger) {
|
|
|
40
40
|
if (!deviceConfig || !deviceConfig.setupComplete) {
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
|
-
const
|
|
44
|
-
const engine = new SyncEngine(storachaClient, workspace);
|
|
43
|
+
const engine = new SyncEngine(workspace);
|
|
45
44
|
await engine.init(deviceConfig);
|
|
46
45
|
const watcher = new FileWatcher({
|
|
47
46
|
workspace,
|
|
@@ -241,6 +240,7 @@ export default function plugin(api) {
|
|
|
241
240
|
.description("Set up a NEW workspace (first device). <delegation> is a file path or base64 CID string.")
|
|
242
241
|
.requiredOption("--agent <id>", "Agent ID")
|
|
243
242
|
.action(async (delegationArg, opts) => {
|
|
243
|
+
let engine = null;
|
|
244
244
|
try {
|
|
245
245
|
const { agentId, workspace } = requireAgent(opts.agent);
|
|
246
246
|
const deviceConfig = await loadDeviceConfig(workspace);
|
|
@@ -263,8 +263,7 @@ export default function plugin(api) {
|
|
|
263
263
|
deviceConfig.setupComplete = true;
|
|
264
264
|
await saveDeviceConfig(workspace, deviceConfig);
|
|
265
265
|
// Initial upload: scan all existing workspace files and sync to Storacha
|
|
266
|
-
|
|
267
|
-
const engine = new SyncEngine(storachaClient, workspace);
|
|
266
|
+
engine = new SyncEngine(workspace);
|
|
268
267
|
await engine.init(deviceConfig);
|
|
269
268
|
const userIgnored = await readIgnoreFile(workspace);
|
|
270
269
|
const ignorePatterns = [
|
|
@@ -293,11 +292,19 @@ export default function plugin(api) {
|
|
|
293
292
|
console.log(`🔥 Storacha workspace ready for ${agentId}!`);
|
|
294
293
|
console.log(`Agent DID: ${agent.did()}`);
|
|
295
294
|
console.log(`Space: ${spaceDID ?? "unknown"}`);
|
|
296
|
-
console.log("\nRestart the gateway to start syncing: `openclaw gateway restart`");
|
|
297
295
|
console.log(`\nTo add another device, run \`openclaw clawracha grant <their-DID> --agent ${agentId}\` here,`);
|
|
298
296
|
console.log(`then \`openclaw clawracha join <upload> <name> --agent <id>\` on the other device.`);
|
|
297
|
+
console.log("\nSync is now active (no gateway restart needed).");
|
|
299
298
|
}
|
|
300
299
|
catch (err) {
|
|
300
|
+
if (engine) {
|
|
301
|
+
try {
|
|
302
|
+
const state = await engine.inspect();
|
|
303
|
+
console.error("\nEngine state at failure:");
|
|
304
|
+
console.error(JSON.stringify(state, null, 2));
|
|
305
|
+
}
|
|
306
|
+
catch { }
|
|
307
|
+
}
|
|
301
308
|
console.error(`Error: ${err.message}`);
|
|
302
309
|
process.exit(1);
|
|
303
310
|
}
|
|
@@ -308,6 +315,7 @@ export default function plugin(api) {
|
|
|
308
315
|
.description("Join an existing workspace from another device. Arguments are file paths or base64 CID strings.")
|
|
309
316
|
.requiredOption("--agent <id>", "Agent ID")
|
|
310
317
|
.action(async (uploadArg, nameArg, opts) => {
|
|
318
|
+
let engine = null;
|
|
311
319
|
try {
|
|
312
320
|
const { agentId, workspace } = requireAgent(opts.agent);
|
|
313
321
|
const deviceConfig = await loadDeviceConfig(workspace);
|
|
@@ -335,8 +343,7 @@ export default function plugin(api) {
|
|
|
335
343
|
await saveDeviceConfig(workspace, deviceConfig);
|
|
336
344
|
// Pull remote state before watcher starts
|
|
337
345
|
let pullCount = 0;
|
|
338
|
-
|
|
339
|
-
const engine = new SyncEngine(storachaClient, workspace);
|
|
346
|
+
engine = new SyncEngine(workspace);
|
|
340
347
|
await engine.init(deviceConfig);
|
|
341
348
|
pullCount = await engine.pullRemote();
|
|
342
349
|
// Save name archive after pull
|
|
@@ -349,9 +356,17 @@ export default function plugin(api) {
|
|
|
349
356
|
console.log(`Agent DID: ${agent.did()}`);
|
|
350
357
|
console.log(`Space: ${spaceDID ?? "unknown"}`);
|
|
351
358
|
console.log(`Pulled ${pullCount} files from remote.`);
|
|
352
|
-
console.log("\
|
|
359
|
+
console.log("\nSync is now active (no gateway restart needed).");
|
|
353
360
|
}
|
|
354
361
|
catch (err) {
|
|
362
|
+
if (engine) {
|
|
363
|
+
try {
|
|
364
|
+
const state = await engine.inspect();
|
|
365
|
+
console.error("\nEngine state at failure:");
|
|
366
|
+
console.error(JSON.stringify(state, null, 2));
|
|
367
|
+
}
|
|
368
|
+
catch { }
|
|
369
|
+
}
|
|
355
370
|
console.error(`Error: ${err.message}`);
|
|
356
371
|
process.exit(1);
|
|
357
372
|
}
|
|
@@ -429,7 +444,6 @@ export default function plugin(api) {
|
|
|
429
444
|
}
|
|
430
445
|
console.log("The target device should run:");
|
|
431
446
|
console.log(` openclaw clawracha join <upload-delegation> <name-delegation> --agent <id>`);
|
|
432
|
-
console.log("\nThen restart the gateway: `openclaw gateway restart`");
|
|
433
447
|
}
|
|
434
448
|
catch (err) {
|
|
435
449
|
console.error(`Error: ${err.message}`);
|
|
@@ -486,10 +500,16 @@ export default function plugin(api) {
|
|
|
486
500
|
console.log(`Not set up. Run \`openclaw clawracha init --agent ${agentId}\` first.`);
|
|
487
501
|
return;
|
|
488
502
|
}
|
|
489
|
-
//
|
|
490
|
-
|
|
491
|
-
const
|
|
492
|
-
|
|
503
|
+
// Use active syncer if available, otherwise spin up temporary engine
|
|
504
|
+
let engine;
|
|
505
|
+
const activeSync = activeSyncers.get(workspace);
|
|
506
|
+
if (activeSync) {
|
|
507
|
+
engine = activeSync.engine;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
engine = new SyncEngine(workspace);
|
|
511
|
+
await engine.init(deviceConfig);
|
|
512
|
+
}
|
|
493
513
|
const state = await engine.inspect();
|
|
494
514
|
console.log(`🔥 Storacha Inspect [${agentId}]`);
|
|
495
515
|
console.log(`Workspace: ${workspace}`);
|
package/dist/sync.d.ts
CHANGED
|
@@ -10,40 +10,43 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { SyncState, FileChange, DeviceConfig } from "./types/index.js";
|
|
12
12
|
import { type PailEntries } from "./utils/differ.js";
|
|
13
|
-
import { Client } from "@storacha/client";
|
|
14
13
|
export declare class SyncEngine {
|
|
15
14
|
private workspace;
|
|
16
15
|
private blocks;
|
|
17
|
-
private
|
|
16
|
+
private state;
|
|
18
17
|
private current;
|
|
19
18
|
private pendingOps;
|
|
20
19
|
private carFile;
|
|
21
|
-
private running;
|
|
22
20
|
private lastSync;
|
|
23
|
-
|
|
24
|
-
constructor(storachaClient: Client, workspace: string);
|
|
21
|
+
constructor(workspace: string);
|
|
25
22
|
/**
|
|
26
|
-
* Initialize sync engine with device config
|
|
23
|
+
* Initialize sync engine with device config.
|
|
24
|
+
* Creates the Storacha client and resolves the UCN name.
|
|
27
25
|
*/
|
|
28
26
|
init(config: DeviceConfig): Promise<void>;
|
|
29
27
|
/**
|
|
30
|
-
*
|
|
28
|
+
* Require running state or throw.
|
|
29
|
+
*/
|
|
30
|
+
private requireRunning;
|
|
31
|
+
/**
|
|
32
|
+
* Process a batch of file changes.
|
|
33
|
+
* Can be called even when not running (accumulates pending ops).
|
|
31
34
|
*/
|
|
32
35
|
processChanges(changes: FileChange[]): Promise<void>;
|
|
33
36
|
/**
|
|
34
|
-
* Execute sync: generate revision, publish, upload, apply remote changes
|
|
37
|
+
* Execute sync: generate revision, publish, upload, apply remote changes.
|
|
35
38
|
*/
|
|
36
39
|
sync(): Promise<void>;
|
|
37
40
|
/**
|
|
38
|
-
* Create CAR and upload to Storacha
|
|
41
|
+
* Create CAR and upload to Storacha.
|
|
39
42
|
*/
|
|
40
43
|
private possiblyUploadCAR;
|
|
41
44
|
/**
|
|
42
|
-
* Get current pail entries as map
|
|
45
|
+
* Get current pail entries as map.
|
|
43
46
|
*/
|
|
44
47
|
getPailEntries(): Promise<PailEntries>;
|
|
45
48
|
/**
|
|
46
|
-
* Apply remote changes to local filesystem
|
|
49
|
+
* Apply remote changes to local filesystem.
|
|
47
50
|
*/
|
|
48
51
|
private applyRemoteChanges;
|
|
49
52
|
/**
|
|
@@ -52,7 +55,7 @@ export declare class SyncEngine {
|
|
|
52
55
|
stop(): void;
|
|
53
56
|
/**
|
|
54
57
|
* Pull all remote state and write to local filesystem.
|
|
55
|
-
* Used by
|
|
58
|
+
* Used by join to overwrite local with remote before watcher starts.
|
|
56
59
|
*/
|
|
57
60
|
pullRemote(): Promise<number>;
|
|
58
61
|
/**
|
package/dist/sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EAEV,YAAY,EACb,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EAEV,YAAY,EACb,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWxE,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,SAAS,EAAE,MAAM;IAK7B;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC/C;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgD3B;;OAEG;YACW,iBAAiB;IAe/B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAc5C;;OAEG;YACW,kBAAkB;IAUhC;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BnC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC;QACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5D,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IAiBI,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC;IAW5B,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;YAM5B,WAAW;CAK1B"}
|
package/dist/sync.js
CHANGED
|
@@ -16,31 +16,32 @@ import { applyRemoteChanges } from "./handlers/remote.js";
|
|
|
16
16
|
import { processChanges } from "./handlers/process.js";
|
|
17
17
|
import { diffRemoteChanges } from "./utils/differ.js";
|
|
18
18
|
import { makeTempCar } from "./utils/tempcar.js";
|
|
19
|
+
import { createStorachaClient } from "./utils/client.js";
|
|
19
20
|
import { decodeDelegation, encodeDelegation } from "./utils/delegation.js";
|
|
20
21
|
export class SyncEngine {
|
|
21
22
|
workspace;
|
|
22
23
|
blocks;
|
|
23
|
-
|
|
24
|
+
state = { running: false };
|
|
24
25
|
current = null;
|
|
25
26
|
pendingOps = [];
|
|
26
27
|
carFile = null;
|
|
27
|
-
running = false;
|
|
28
28
|
lastSync = null;
|
|
29
|
-
|
|
30
|
-
constructor(storachaClient, workspace) {
|
|
31
|
-
this.storachaClient = storachaClient;
|
|
29
|
+
constructor(workspace) {
|
|
32
30
|
this.workspace = workspace;
|
|
33
31
|
this.blocks = createWorkspaceBlockstore(workspace);
|
|
34
32
|
}
|
|
35
33
|
/**
|
|
36
|
-
* Initialize sync engine with device config
|
|
34
|
+
* Initialize sync engine with device config.
|
|
35
|
+
* Creates the Storacha client and resolves the UCN name.
|
|
37
36
|
*/
|
|
38
37
|
async init(config) {
|
|
38
|
+
const storachaClient = await createStorachaClient(config);
|
|
39
39
|
const agent = Agent.parse(config.agentKey);
|
|
40
|
+
let name;
|
|
40
41
|
if (config.nameArchive) {
|
|
41
42
|
// Restore from previously saved archive (has full state)
|
|
42
43
|
const archiveBytes = decodeDelegation(config.nameArchive);
|
|
43
|
-
|
|
44
|
+
name = await Name.extract(agent, archiveBytes);
|
|
44
45
|
}
|
|
45
46
|
else if (config.nameDelegation) {
|
|
46
47
|
// Reconstruct from delegation (granted by another device)
|
|
@@ -49,14 +50,15 @@ export class SyncEngine {
|
|
|
49
50
|
const { ok: delegation } = await extract(nameBytes);
|
|
50
51
|
if (!delegation)
|
|
51
52
|
throw new Error("Failed to extract name delegation");
|
|
52
|
-
|
|
53
|
+
name = Name.from(agent, [delegation]);
|
|
53
54
|
}
|
|
54
55
|
else {
|
|
55
56
|
// First device — create a new name
|
|
56
|
-
|
|
57
|
+
name = await Name.create(agent);
|
|
57
58
|
}
|
|
59
|
+
this.state = { running: true, name, storachaClient };
|
|
58
60
|
try {
|
|
59
|
-
const result = await Revision.resolve(this.blocks,
|
|
61
|
+
const result = await Revision.resolve(this.blocks, name);
|
|
60
62
|
this.current = result.value;
|
|
61
63
|
await this.storeBlocks(result.additions);
|
|
62
64
|
}
|
|
@@ -68,10 +70,19 @@ export class SyncEngine {
|
|
|
68
70
|
throw err;
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
|
-
this.running = true;
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
|
-
*
|
|
75
|
+
* Require running state or throw.
|
|
76
|
+
*/
|
|
77
|
+
requireRunning() {
|
|
78
|
+
if (!this.state.running) {
|
|
79
|
+
throw new Error("Sync engine not initialized");
|
|
80
|
+
}
|
|
81
|
+
return this.state;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Process a batch of file changes.
|
|
85
|
+
* Can be called even when not running (accumulates pending ops).
|
|
75
86
|
*/
|
|
76
87
|
async processChanges(changes) {
|
|
77
88
|
if (!this.carFile) {
|
|
@@ -81,18 +92,16 @@ export class SyncEngine {
|
|
|
81
92
|
this.pendingOps.push(...pendingOps);
|
|
82
93
|
}
|
|
83
94
|
/**
|
|
84
|
-
* Execute sync: generate revision, publish, upload, apply remote changes
|
|
95
|
+
* Execute sync: generate revision, publish, upload, apply remote changes.
|
|
85
96
|
*/
|
|
86
97
|
async sync() {
|
|
87
|
-
|
|
88
|
-
throw new Error("Sync engine not initialized");
|
|
89
|
-
}
|
|
98
|
+
const { name } = this.requireRunning();
|
|
90
99
|
const beforeEntries = await this.getPailEntries();
|
|
91
100
|
if (this.pendingOps.length > 0) {
|
|
92
101
|
if (!this.carFile) {
|
|
93
102
|
throw new Error("CAR file not initialized");
|
|
94
103
|
}
|
|
95
|
-
const result = await applyPendingOps(this.blocks,
|
|
104
|
+
const result = await applyPendingOps(this.blocks, name, this.current, this.pendingOps);
|
|
96
105
|
this.current = result.current;
|
|
97
106
|
for (const block of result.revisionBlocks) {
|
|
98
107
|
await this.carFile.put(block);
|
|
@@ -102,7 +111,7 @@ export class SyncEngine {
|
|
|
102
111
|
else {
|
|
103
112
|
// No pending ops — just pull remote
|
|
104
113
|
try {
|
|
105
|
-
const result = await Revision.resolve(this.blocks,
|
|
114
|
+
const result = await Revision.resolve(this.blocks, name, {
|
|
106
115
|
base: this.current ?? undefined,
|
|
107
116
|
});
|
|
108
117
|
await this.storeBlocks(result.additions);
|
|
@@ -125,15 +134,16 @@ export class SyncEngine {
|
|
|
125
134
|
this.lastSync = Date.now();
|
|
126
135
|
}
|
|
127
136
|
/**
|
|
128
|
-
* Create CAR and upload to Storacha
|
|
137
|
+
* Create CAR and upload to Storacha.
|
|
129
138
|
*/
|
|
130
139
|
async possiblyUploadCAR() {
|
|
131
140
|
if (this.carFile) {
|
|
141
|
+
const { storachaClient } = this.requireRunning();
|
|
132
142
|
const readableCar = await this.carFile.switchToReadable();
|
|
133
143
|
this.carFile = null;
|
|
134
144
|
if (readableCar) {
|
|
135
145
|
try {
|
|
136
|
-
await
|
|
146
|
+
await storachaClient.uploadCAR(readableCar.readable);
|
|
137
147
|
}
|
|
138
148
|
finally {
|
|
139
149
|
await readableCar.cleanup();
|
|
@@ -142,7 +152,7 @@ export class SyncEngine {
|
|
|
142
152
|
}
|
|
143
153
|
}
|
|
144
154
|
/**
|
|
145
|
-
* Get current pail entries as map
|
|
155
|
+
* Get current pail entries as map.
|
|
146
156
|
*/
|
|
147
157
|
async getPailEntries() {
|
|
148
158
|
const entries = new Map();
|
|
@@ -156,7 +166,7 @@ export class SyncEngine {
|
|
|
156
166
|
return entries;
|
|
157
167
|
}
|
|
158
168
|
/**
|
|
159
|
-
* Apply remote changes to local filesystem
|
|
169
|
+
* Apply remote changes to local filesystem.
|
|
160
170
|
*/
|
|
161
171
|
async applyRemoteChanges(changedPaths, entries) {
|
|
162
172
|
await applyRemoteChanges(changedPaths, entries, this.workspace, {
|
|
@@ -168,17 +178,16 @@ export class SyncEngine {
|
|
|
168
178
|
* Mark the engine as stopped.
|
|
169
179
|
*/
|
|
170
180
|
stop() {
|
|
171
|
-
this.
|
|
181
|
+
this.state = { running: false };
|
|
172
182
|
}
|
|
173
183
|
/**
|
|
174
184
|
* Pull all remote state and write to local filesystem.
|
|
175
|
-
* Used by
|
|
185
|
+
* Used by join to overwrite local with remote before watcher starts.
|
|
176
186
|
*/
|
|
177
187
|
async pullRemote() {
|
|
178
|
-
|
|
179
|
-
throw new Error("Sync engine not initialized");
|
|
188
|
+
const { name } = this.requireRunning();
|
|
180
189
|
try {
|
|
181
|
-
const result = await Revision.resolve(this.blocks,
|
|
190
|
+
const result = await Revision.resolve(this.blocks, name, {
|
|
182
191
|
base: this.current ?? undefined,
|
|
183
192
|
});
|
|
184
193
|
await this.storeBlocks(result.additions);
|
|
@@ -215,13 +224,13 @@ export class SyncEngine {
|
|
|
215
224
|
key: op.key,
|
|
216
225
|
value: op.value?.toString(),
|
|
217
226
|
})),
|
|
218
|
-
running: this.running,
|
|
227
|
+
running: this.state.running,
|
|
219
228
|
};
|
|
220
229
|
}
|
|
221
230
|
async status() {
|
|
222
231
|
const entries = await this.getPailEntries();
|
|
223
232
|
return {
|
|
224
|
-
running: this.running,
|
|
233
|
+
running: this.state.running,
|
|
225
234
|
lastSync: this.lastSync,
|
|
226
235
|
root: this.current?.root ?? null,
|
|
227
236
|
entryCount: entries.size,
|
|
@@ -229,9 +238,8 @@ export class SyncEngine {
|
|
|
229
238
|
};
|
|
230
239
|
}
|
|
231
240
|
async exportNameArchive() {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const bytes = await this.name.archive();
|
|
241
|
+
const { name } = this.requireRunning();
|
|
242
|
+
const bytes = await name.archive();
|
|
235
243
|
return encodeDelegation(bytes);
|
|
236
244
|
}
|
|
237
245
|
async storeBlocks(blocks) {
|