Skip to content

Commit 2e9c94f

Browse files
authored
refactor (#535)
1 parent 2084d99 commit 2e9c94f

File tree

7 files changed

+208
-139
lines changed

7 files changed

+208
-139
lines changed

packages/cli/src/internal/effect/ChopsticksMultiChain.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import { Context, Data, Effect, Layer } from "effect";
99
import type { HexString } from "@polkadot/util/types";
10+
import type { BuildBlockMode } from "@acala-network/chopsticks";
1011
import { createLogger } from "@moonwall/util";
1112
import {
1213
type ChopsticksConfig,
@@ -19,6 +20,16 @@ import { type ChopsticksServiceImpl, launchChopsticksEffect } from "./launchChop
1920

2021
const logger = createLogger({ name: "ChopsticksMultiChain" });
2122

23+
/**
24+
* Extract a single endpoint string from the config.
25+
* The ChopsticksConfig endpoint can be a string, array of strings, or undefined.
26+
*/
27+
const getEndpointString = (endpoint: string | string[] | undefined): string | undefined => {
28+
if (typeof endpoint === "string") return endpoint;
29+
if (Array.isArray(endpoint)) return endpoint[0];
30+
return undefined;
31+
};
32+
2233
// =============================================================================
2334
// Error Types
2435
// =============================================================================
@@ -352,7 +363,7 @@ export const ChopsticksMultiChainLayer = (
352363
catch: (cause) =>
353364
new ChopsticksSetupError({
354365
cause,
355-
endpoint: config.relay.endpoint,
366+
endpoint: getEndpointString(config.relay.endpoint),
356367
}),
357368
});
358369
cleanups.push(
@@ -370,7 +381,7 @@ export const ChopsticksMultiChainLayer = (
370381
catch: (cause) =>
371382
new ChopsticksSetupError({
372383
cause,
373-
endpoint: paraConfig.endpoint,
384+
endpoint: getEndpointString(paraConfig.endpoint),
374385
}),
375386
});
376387
cleanups.push(
@@ -412,13 +423,15 @@ export const createPolkadotMoonbeamConfig = (
412423
type: "relay",
413424
endpoint: "wss://rpc.polkadot.io",
414425
port: relayPort,
426+
"build-block-mode": "Manual" as BuildBlockMode,
415427
},
416428
parachains: [
417429
{
418430
type: "parachain",
419431
paraId: 2004, // Moonbeam on Polkadot
420432
endpoint: "wss://wss.api.moonbeam.network",
421433
port: moonbeamPort,
434+
"build-block-mode": "Manual" as BuildBlockMode,
422435
},
423436
],
424437
});
@@ -438,13 +451,15 @@ export const createKusamaMoonriverConfig = (
438451
type: "relay",
439452
endpoint: "wss://kusama-rpc.polkadot.io",
440453
port: relayPort,
454+
"build-block-mode": "Manual" as BuildBlockMode,
441455
},
442456
parachains: [
443457
{
444458
type: "parachain",
445459
paraId: 2023, // Moonriver on Kusama
446460
endpoint: "wss://wss.api.moonriver.moonbeam.network",
447461
port: moonriverPort,
462+
"build-block-mode": "Manual" as BuildBlockMode,
448463
},
449464
],
450465
});

packages/cli/src/internal/effect/ChopsticksService.ts

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@
33
*
44
* This service provides a type-safe, Effect-based interface to @acala-network/chopsticks,
55
* replacing the previous CLI-subprocess approach with direct programmatic control.
6+
*
7+
* The configuration type (ChopsticksConfig) is imported directly from @acala-network/chopsticks
8+
* to ensure it stays in sync with upstream changes and supports all config options like rpc-timeout.
69
*/
710

811
import { Context, Data, Effect } from "effect";
9-
import type { Blockchain, BuildBlockMode } from "@acala-network/chopsticks";
12+
import type { Blockchain, BuildBlockMode, fetchConfig } from "@acala-network/chopsticks";
1013
import type { HexString } from "@polkadot/util/types";
1114

15+
/**
16+
* The ChopsticksConfig type, derived from the fetchConfig return type.
17+
*
18+
* This ensures our type stays in sync with upstream chopsticks changes.
19+
* The config uses kebab-case keys as defined by chopsticks (e.g., 'rpc-timeout',
20+
* 'build-block-mode', 'mock-signature-host').
21+
*/
22+
export type ChopsticksConfig = Awaited<ReturnType<typeof fetchConfig>>;
23+
1224
// =============================================================================
1325
// Error Types
1426
// =============================================================================
@@ -80,34 +92,6 @@ export type ChopsticksError =
8092
// Configuration Types
8193
// =============================================================================
8294

83-
/**
84-
* Configuration for launching a chopsticks instance
85-
*/
86-
export interface ChopsticksConfig {
87-
/** WebSocket endpoint to fork from (e.g., "wss://rpc.polkadot.io") */
88-
readonly endpoint: string;
89-
/** Block number or hash to fork from (defaults to latest finalized) */
90-
readonly block?: string | number | null;
91-
/** Port to listen on (defaults to 8000) */
92-
readonly port?: number;
93-
/** Host to bind to (defaults to "127.0.0.1") */
94-
readonly host?: string;
95-
/** Block building mode: "batch" | "manual" | "instant" */
96-
readonly buildBlockMode?: BuildBlockMode;
97-
/** Path to WASM override file */
98-
readonly wasmOverride?: string;
99-
/** Whether to allow unresolved imports in WASM */
100-
readonly allowUnresolvedImports?: boolean;
101-
/** Whether to mock signature verification */
102-
readonly mockSignatureHost?: boolean;
103-
/** Path to SQLite database for caching */
104-
readonly db?: string;
105-
/** Storage overrides to apply */
106-
readonly importStorage?: Record<string, Record<string, unknown>>;
107-
/** Runtime log level (0-5) */
108-
readonly runtimeLogLevel?: number;
109-
}
110-
11195
/**
11296
* Result from creating a new block
11397
*/

packages/cli/src/internal/effect/__tests__/ChopsticksMultiChain.test.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, it, expect } from "vitest";
22
import { Effect, Layer } from "effect";
3+
import { BuildBlockMode } from "@acala-network/chopsticks";
34
import {
45
ChopsticksOrchestrationError,
56
ChopsticksMultiChainService,
@@ -83,48 +84,53 @@ describe("ChopsticksMultiChain - Phase 4: Multi-chain XCM Support", () => {
8384
});
8485

8586
describe("Configuration Types", () => {
86-
it("should create valid RelayChainConfig", () => {
87+
it("should create valid RelayChainConfig with kebab-case keys", () => {
8788
const config: RelayChainConfig = {
8889
type: "relay",
8990
endpoint: "wss://rpc.polkadot.io",
9091
port: 8000,
92+
"build-block-mode": BuildBlockMode.Manual,
9193
};
9294

9395
expect(config.type).toBe("relay");
9496
expect(config.endpoint).toBe("wss://rpc.polkadot.io");
9597
});
9698

97-
it("should create valid ParachainConfig", () => {
99+
it("should create valid ParachainConfig with kebab-case keys", () => {
98100
const config: ParachainConfig = {
99101
type: "parachain",
100102
paraId: 2000,
101103
endpoint: "wss://moonbeam.rpc.io",
102104
port: 8001,
105+
"build-block-mode": BuildBlockMode.Manual,
103106
};
104107

105108
expect(config.type).toBe("parachain");
106109
expect(config.paraId).toBe(2000);
107110
});
108111

109-
it("should create valid MultiChainConfig", () => {
112+
it("should create valid MultiChainConfig with kebab-case keys", () => {
110113
const config: MultiChainConfig = {
111114
relay: {
112115
type: "relay",
113116
endpoint: "wss://rpc.polkadot.io",
114117
port: 8000,
118+
"build-block-mode": BuildBlockMode.Manual,
115119
},
116120
parachains: [
117121
{
118122
type: "parachain",
119123
paraId: 2000,
120124
endpoint: "wss://moonbeam.rpc.io",
121125
port: 8001,
126+
"build-block-mode": BuildBlockMode.Manual,
122127
},
123128
{
124129
type: "parachain",
125130
paraId: 2001,
126131
endpoint: "wss://acala.rpc.io",
127132
port: 8002,
133+
"build-block-mode": BuildBlockMode.Manual,
128134
},
129135
],
130136
};
@@ -364,13 +370,15 @@ describe("ChopsticksMultiChain - Phase 4: Multi-chain XCM Support", () => {
364370
type: "relay",
365371
endpoint: "wss://test.io",
366372
port: 8000,
373+
"build-block-mode": BuildBlockMode.Manual,
367374
},
368375
parachains: [
369376
{
370377
type: "parachain",
371378
paraId: 2000,
372379
endpoint: "wss://para.test.io",
373380
port: 8001,
381+
"build-block-mode": BuildBlockMode.Manual,
374382
},
375383
],
376384
};
@@ -389,6 +397,7 @@ describe("ChopsticksMultiChain - Phase 4: Multi-chain XCM Support", () => {
389397
type: "relay",
390398
endpoint: "wss://test.io",
391399
port: 8000,
400+
"build-block-mode": BuildBlockMode.Manual,
392401
},
393402
parachains: [],
394403
};
@@ -444,13 +453,15 @@ describe.skip("ChopsticksMultiChain - Integration Tests", () => {
444453
type: "relay",
445454
endpoint: "wss://rpc.polkadot.io",
446455
port: 8000,
456+
"build-block-mode": BuildBlockMode.Manual,
447457
},
448458
parachains: [
449459
{
450460
type: "parachain",
451461
paraId: 2004,
452462
endpoint: "wss://wss.api.moonbeam.network",
453463
port: 8001,
464+
"build-block-mode": BuildBlockMode.Manual,
454465
},
455466
],
456467
});

packages/cli/src/internal/effect/__tests__/ChopsticksService.test.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,39 +218,46 @@ describe("ChopsticksService - Phase 1: Types and Errors", () => {
218218
});
219219

220220
describe("Config Type Validation", () => {
221-
it("should allow creating a valid ChopsticksConfig", () => {
221+
it("should allow creating a valid ChopsticksConfig with kebab-case keys", () => {
222+
// ChopsticksConfig uses kebab-case keys matching chopsticks' native format
222223
const config: ChopsticksConfig = {
223224
endpoint: "wss://rpc.polkadot.io",
224225
block: 12345,
225226
port: 8000,
226227
host: "127.0.0.1",
227-
buildBlockMode: BuildBlockMode.Manual,
228-
wasmOverride: "/path/to/wasm",
229-
allowUnresolvedImports: true,
230-
mockSignatureHost: true,
228+
"build-block-mode": BuildBlockMode.Manual,
229+
"wasm-override": "/path/to/wasm",
230+
"allow-unresolved-imports": true,
231+
"mock-signature-host": true,
231232
db: "./chopsticks.db",
232-
runtimeLogLevel: 3,
233+
"runtime-log-level": 3,
234+
"rpc-timeout": 30000, // New field supported via chopsticks type
233235
};
234236

235237
expect(config.endpoint).toBe("wss://rpc.polkadot.io");
236238
expect(config.block).toBe(12345);
237239
expect(config.port).toBe(8000);
240+
expect(config["rpc-timeout"]).toBe(30000);
238241
});
239242

240-
it("should allow minimal ChopsticksConfig with only required fields", () => {
243+
it("should allow ChopsticksConfig with required port and build-block-mode", () => {
244+
// The chopsticks Config type has port and build-block-mode as required after parsing
241245
const config: ChopsticksConfig = {
242246
endpoint: "wss://rpc.polkadot.io",
247+
port: 8000,
248+
"build-block-mode": BuildBlockMode.Manual,
243249
};
244250

245251
expect(config.endpoint).toBe("wss://rpc.polkadot.io");
246-
expect(config.block).toBeUndefined();
247-
expect(config.port).toBeUndefined();
252+
expect(config.port).toBe(8000);
253+
expect(config["build-block-mode"]).toBe(BuildBlockMode.Manual);
248254
});
249255

250256
it("should allow providing ChopsticksConfig via Layer", async () => {
251257
const config: ChopsticksConfig = {
252258
endpoint: "wss://test.io",
253259
port: 9000,
260+
"build-block-mode": BuildBlockMode.Manual,
254261
};
255262

256263
const configLayer = Layer.succeed(ChopsticksConfigTag, config);

0 commit comments

Comments
 (0)