moonwall 1.0.0-dev.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.
- package/LICENSE +681 -0
- package/README.md +54 -0
- package/config_schema.json +811 -0
- package/dist/api/constants/accounts.d.ts +36 -0
- package/dist/api/constants/accounts.d.ts.map +1 -0
- package/dist/api/constants/accounts.js +67 -0
- package/dist/api/constants/chain.d.ts +134 -0
- package/dist/api/constants/chain.d.ts.map +1 -0
- package/dist/api/constants/chain.js +149 -0
- package/dist/api/constants/index.d.ts +4 -0
- package/dist/api/constants/index.d.ts.map +1 -0
- package/dist/api/constants/index.js +3 -0
- package/dist/api/constants/smartContract.d.ts +29 -0
- package/dist/api/constants/smartContract.d.ts.map +1 -0
- package/dist/api/constants/smartContract.js +118 -0
- package/dist/api/testing/blocks.d.ts +59 -0
- package/dist/api/testing/blocks.d.ts.map +1 -0
- package/dist/api/testing/blocks.js +147 -0
- package/dist/api/testing/contracts.d.ts +5 -0
- package/dist/api/testing/contracts.d.ts.map +1 -0
- package/dist/api/testing/contracts.js +32 -0
- package/dist/api/testing/ethers.d.ts +3 -0
- package/dist/api/testing/ethers.d.ts.map +1 -0
- package/dist/api/testing/ethers.js +38 -0
- package/dist/api/testing/events.d.ts +12 -0
- package/dist/api/testing/events.d.ts.map +1 -0
- package/dist/api/testing/events.js +23 -0
- package/dist/api/testing/extrinsics.d.ts +5 -0
- package/dist/api/testing/extrinsics.d.ts.map +1 -0
- package/dist/api/testing/extrinsics.js +10 -0
- package/dist/api/testing/index.d.ts +9 -0
- package/dist/api/testing/index.d.ts.map +1 -0
- package/dist/api/testing/index.js +8 -0
- package/dist/api/testing/jumping.d.ts +8 -0
- package/dist/api/testing/jumping.d.ts.map +1 -0
- package/dist/api/testing/jumping.js +78 -0
- package/dist/api/testing/providers.d.ts +18 -0
- package/dist/api/testing/providers.d.ts.map +1 -0
- package/dist/api/testing/providers.js +34 -0
- package/dist/api/testing/viem.d.ts +139 -0
- package/dist/api/testing/viem.d.ts.map +1 -0
- package/dist/api/testing/viem.js +247 -0
- package/dist/api/types/config.d.ts +609 -0
- package/dist/api/types/config.d.ts.map +1 -0
- package/dist/api/types/config.js +1 -0
- package/dist/api/types/context.d.ts +125 -0
- package/dist/api/types/context.d.ts.map +1 -0
- package/dist/api/types/context.js +1 -0
- package/dist/api/types/contracts.d.ts +66 -0
- package/dist/api/types/contracts.d.ts.map +1 -0
- package/dist/api/types/contracts.js +1 -0
- package/dist/api/types/eth.d.ts +3 -0
- package/dist/api/types/eth.d.ts.map +1 -0
- package/dist/api/types/eth.js +1 -0
- package/dist/api/types/foundations.d.ts +11 -0
- package/dist/api/types/foundations.d.ts.map +1 -0
- package/dist/api/types/foundations.js +1 -0
- package/dist/api/types/helpers.d.ts +7 -0
- package/dist/api/types/helpers.d.ts.map +1 -0
- package/dist/api/types/helpers.js +1 -0
- package/dist/api/types/index.d.ts +8 -0
- package/dist/api/types/index.d.ts.map +1 -0
- package/dist/api/types/index.js +7 -0
- package/dist/api/types/runner.d.ts +490 -0
- package/dist/api/types/runner.d.ts.map +1 -0
- package/dist/api/types/runner.js +1 -0
- package/dist/cli/cmds/components/LogViewer.d.ts +17 -0
- package/dist/cli/cmds/components/LogViewer.d.ts.map +1 -0
- package/dist/cli/cmds/components/LogViewer.js +171 -0
- package/dist/cli/cmds/entrypoint.d.ts +6 -0
- package/dist/cli/cmds/entrypoint.d.ts.map +1 -0
- package/dist/cli/cmds/entrypoint.js +192 -0
- package/dist/cli/cmds/interactiveCmds/chopsticksIntCmds.d.ts +2 -0
- package/dist/cli/cmds/interactiveCmds/chopsticksIntCmds.d.ts.map +1 -0
- package/dist/cli/cmds/interactiveCmds/chopsticksIntCmds.js +117 -0
- package/dist/cli/cmds/interactiveCmds/devIntCmds.d.ts +2 -0
- package/dist/cli/cmds/interactiveCmds/devIntCmds.d.ts.map +1 -0
- package/dist/cli/cmds/interactiveCmds/devIntCmds.js +103 -0
- package/dist/cli/cmds/interactiveCmds/index.d.ts +4 -0
- package/dist/cli/cmds/interactiveCmds/index.d.ts.map +1 -0
- package/dist/cli/cmds/interactiveCmds/index.js +3 -0
- package/dist/cli/cmds/interactiveCmds/zombieIntCmds.d.ts +2 -0
- package/dist/cli/cmds/interactiveCmds/zombieIntCmds.d.ts.map +1 -0
- package/dist/cli/cmds/interactiveCmds/zombieIntCmds.js +32 -0
- package/dist/cli/cmds/main.d.ts +2 -0
- package/dist/cli/cmds/main.d.ts.map +1 -0
- package/dist/cli/cmds/main.js +336 -0
- package/dist/cli/cmds/runNetwork.d.ts +3 -0
- package/dist/cli/cmds/runNetwork.d.ts.map +1 -0
- package/dist/cli/cmds/runNetwork.js +292 -0
- package/dist/cli/cmds/runTests.d.ts +12 -0
- package/dist/cli/cmds/runTests.d.ts.map +1 -0
- package/dist/cli/cmds/runTests.js +257 -0
- package/dist/cli/internal/cmdFunctions/downloader.d.ts +4 -0
- package/dist/cli/internal/cmdFunctions/downloader.d.ts.map +1 -0
- package/dist/cli/internal/cmdFunctions/downloader.js +49 -0
- package/dist/cli/internal/cmdFunctions/fetchArtifact.d.ts +10 -0
- package/dist/cli/internal/cmdFunctions/fetchArtifact.d.ts.map +1 -0
- package/dist/cli/internal/cmdFunctions/fetchArtifact.js +145 -0
- package/dist/cli/internal/cmdFunctions/index.d.ts +5 -0
- package/dist/cli/internal/cmdFunctions/index.d.ts.map +1 -0
- package/dist/cli/internal/cmdFunctions/index.js +4 -0
- package/dist/cli/internal/cmdFunctions/initialisation.d.ts +20 -0
- package/dist/cli/internal/cmdFunctions/initialisation.d.ts.map +1 -0
- package/dist/cli/internal/cmdFunctions/initialisation.js +150 -0
- package/dist/cli/internal/cmdFunctions/tempLogs.d.ts +3 -0
- package/dist/cli/internal/cmdFunctions/tempLogs.d.ts.map +1 -0
- package/dist/cli/internal/cmdFunctions/tempLogs.js +37 -0
- package/dist/cli/internal/commandParsers.d.ts +59 -0
- package/dist/cli/internal/commandParsers.d.ts.map +1 -0
- package/dist/cli/internal/commandParsers.js +305 -0
- package/dist/cli/internal/deriveTestIds.d.ts +8 -0
- package/dist/cli/internal/deriveTestIds.d.ts.map +1 -0
- package/dist/cli/internal/deriveTestIds.js +123 -0
- package/dist/cli/internal/effect/index.d.ts +6 -0
- package/dist/cli/internal/effect/index.d.ts.map +1 -0
- package/dist/cli/internal/effect/index.js +5 -0
- package/dist/cli/internal/fileCheckers.d.ts +11 -0
- package/dist/cli/internal/fileCheckers.d.ts.map +1 -0
- package/dist/cli/internal/fileCheckers.js +165 -0
- package/dist/cli/internal/foundations/index.d.ts +4 -0
- package/dist/cli/internal/foundations/index.d.ts.map +1 -0
- package/dist/cli/internal/foundations/index.js +4 -0
- package/dist/cli/internal/index.d.ts +12 -0
- package/dist/cli/internal/index.d.ts.map +1 -0
- package/dist/cli/internal/index.js +11 -0
- package/dist/cli/internal/launcherCommon.d.ts +4 -0
- package/dist/cli/internal/launcherCommon.d.ts.map +1 -0
- package/dist/cli/internal/launcherCommon.js +130 -0
- package/dist/cli/internal/localNode.d.ts +16 -0
- package/dist/cli/internal/localNode.d.ts.map +1 -0
- package/dist/cli/internal/localNode.js +362 -0
- package/dist/cli/internal/logging.d.ts +2 -0
- package/dist/cli/internal/logging.d.ts.map +1 -0
- package/dist/cli/internal/logging.js +26 -0
- package/dist/cli/internal/node.d.ts +33 -0
- package/dist/cli/internal/node.d.ts.map +1 -0
- package/dist/cli/internal/node.js +228 -0
- package/dist/cli/internal/processHelpers.d.ts +17 -0
- package/dist/cli/internal/processHelpers.d.ts.map +1 -0
- package/dist/cli/internal/processHelpers.js +56 -0
- package/dist/cli/internal/providerFactories.d.ts +48 -0
- package/dist/cli/internal/providerFactories.d.ts.map +1 -0
- package/dist/cli/internal/providerFactories.js +442 -0
- package/dist/cli/internal/testIdParser.d.ts +34 -0
- package/dist/cli/internal/testIdParser.d.ts.map +1 -0
- package/dist/cli/internal/testIdParser.js +167 -0
- package/dist/cli/lib/binariesHelpers.d.ts +15 -0
- package/dist/cli/lib/binariesHelpers.d.ts.map +1 -0
- package/dist/cli/lib/binariesHelpers.js +99 -0
- package/dist/cli/lib/configReader.d.ts +8 -0
- package/dist/cli/lib/configReader.d.ts.map +1 -0
- package/dist/cli/lib/configReader.js +115 -0
- package/dist/cli/lib/contractFunctions.d.ts +2 -0
- package/dist/cli/lib/contractFunctions.d.ts.map +1 -0
- package/dist/cli/lib/contractFunctions.js +2 -0
- package/dist/cli/lib/globalContext.d.ts +46 -0
- package/dist/cli/lib/globalContext.d.ts.map +1 -0
- package/dist/cli/lib/globalContext.js +710 -0
- package/dist/cli/lib/governanceProcedures.d.ts +27 -0
- package/dist/cli/lib/governanceProcedures.d.ts.map +1 -0
- package/dist/cli/lib/governanceProcedures.js +458 -0
- package/dist/cli/lib/handlers/index.d.ts +5 -0
- package/dist/cli/lib/handlers/index.d.ts.map +1 -0
- package/dist/cli/lib/handlers/index.js +5 -0
- package/dist/cli/lib/repoDefinitions/index.d.ts +6 -0
- package/dist/cli/lib/repoDefinitions/index.d.ts.map +1 -0
- package/dist/cli/lib/repoDefinitions/index.js +21 -0
- package/dist/cli/lib/repoDefinitions/moonbeam.d.ts +4 -0
- package/dist/cli/lib/repoDefinitions/moonbeam.d.ts.map +1 -0
- package/dist/cli/lib/repoDefinitions/moonbeam.js +30 -0
- package/dist/cli/lib/repoDefinitions/polkadot.d.ts +4 -0
- package/dist/cli/lib/repoDefinitions/polkadot.d.ts.map +1 -0
- package/dist/cli/lib/repoDefinitions/polkadot.js +11 -0
- package/dist/cli/lib/repoDefinitions/tanssi.d.ts +4 -0
- package/dist/cli/lib/repoDefinitions/tanssi.d.ts.map +1 -0
- package/dist/cli/lib/repoDefinitions/tanssi.js +14 -0
- package/dist/cli/lib/rpcFunctions.d.ts +2 -0
- package/dist/cli/lib/rpcFunctions.d.ts.map +1 -0
- package/dist/cli/lib/rpcFunctions.js +26 -0
- package/dist/cli/lib/runnerContext.d.ts +32 -0
- package/dist/cli/lib/runnerContext.d.ts.map +1 -0
- package/dist/cli/lib/runnerContext.js +156 -0
- package/dist/cli/lib/shardManager.d.ts +40 -0
- package/dist/cli/lib/shardManager.d.ts.map +1 -0
- package/dist/cli/lib/shardManager.js +80 -0
- package/dist/cli/lib/upgradeProcedures.d.ts +5 -0
- package/dist/cli/lib/upgradeProcedures.d.ts.map +1 -0
- package/dist/cli/lib/upgradeProcedures.js +221 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/contracts/contractInteraction.d.ts +17 -0
- package/dist/contracts/contractInteraction.d.ts.map +1 -0
- package/dist/contracts/contractInteraction.js +170 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/foundations/chopsticks/handler.d.ts +3 -0
- package/dist/foundations/chopsticks/handler.d.ts.map +1 -0
- package/dist/foundations/chopsticks/handler.js +93 -0
- package/dist/foundations/chopsticks/helpers.d.ts +27 -0
- package/dist/foundations/chopsticks/helpers.d.ts.map +1 -0
- package/dist/foundations/chopsticks/helpers.js +133 -0
- package/dist/foundations/dev/handler.d.ts +3 -0
- package/dist/foundations/dev/handler.d.ts.map +1 -0
- package/dist/foundations/dev/handler.js +136 -0
- package/dist/foundations/dev/helpers.d.ts +27 -0
- package/dist/foundations/dev/helpers.d.ts.map +1 -0
- package/dist/foundations/dev/helpers.js +161 -0
- package/dist/foundations/read-only/handler.d.ts +3 -0
- package/dist/foundations/read-only/handler.d.ts.map +1 -0
- package/dist/foundations/read-only/handler.js +32 -0
- package/dist/foundations/zombie/handler.d.ts +3 -0
- package/dist/foundations/zombie/handler.d.ts.map +1 -0
- package/dist/foundations/zombie/handler.js +92 -0
- package/dist/foundations/zombie/helpers.d.ts +16 -0
- package/dist/foundations/zombie/helpers.d.ts.map +1 -0
- package/dist/foundations/zombie/helpers.js +97 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/internal/common.d.ts +3 -0
- package/dist/internal/common.d.ts.map +1 -0
- package/dist/internal/common.js +41 -0
- package/dist/internal/index.d.ts +4 -0
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +3 -0
- package/dist/internal/logger.d.ts +24 -0
- package/dist/internal/logger.d.ts.map +1 -0
- package/dist/internal/logger.js +66 -0
- package/dist/internal/logging.d.ts +7 -0
- package/dist/internal/logging.d.ts.map +1 -0
- package/dist/internal/logging.js +36 -0
- package/dist/moondebug.d.ts +3 -0
- package/dist/moondebug.d.ts.map +1 -0
- package/dist/moondebug.js +2 -0
- package/dist/services/cache/FileLock.d.ts +11 -0
- package/dist/services/cache/FileLock.d.ts.map +1 -0
- package/dist/services/cache/FileLock.js +68 -0
- package/dist/services/cache/StartupCacheService.d.ts +23 -0
- package/dist/services/cache/StartupCacheService.d.ts.map +1 -0
- package/dist/services/cache/StartupCacheService.js +159 -0
- package/dist/services/cache/index.d.ts +3 -0
- package/dist/services/cache/index.d.ts.map +1 -0
- package/dist/services/cache/index.js +2 -0
- package/dist/services/chopsticks/ChopsticksMultiChain.d.ts +158 -0
- package/dist/services/chopsticks/ChopsticksMultiChain.d.ts.map +1 -0
- package/dist/services/chopsticks/ChopsticksMultiChain.js +282 -0
- package/dist/services/chopsticks/ChopsticksService.d.ts +313 -0
- package/dist/services/chopsticks/ChopsticksService.d.ts.map +1 -0
- package/dist/services/chopsticks/ChopsticksService.js +77 -0
- package/dist/services/chopsticks/chopsticksConfigParser.d.ts +40 -0
- package/dist/services/chopsticks/chopsticksConfigParser.d.ts.map +1 -0
- package/dist/services/chopsticks/chopsticksConfigParser.js +201 -0
- package/dist/services/chopsticks/index.d.ts +5 -0
- package/dist/services/chopsticks/index.d.ts.map +1 -0
- package/dist/services/chopsticks/index.js +4 -0
- package/dist/services/chopsticks/launchChopsticksEffect.d.ts +225 -0
- package/dist/services/chopsticks/launchChopsticksEffect.d.ts.map +1 -0
- package/dist/services/chopsticks/launchChopsticksEffect.js +623 -0
- package/dist/services/config/configAccessors.d.ts +41 -0
- package/dist/services/config/configAccessors.d.ts.map +1 -0
- package/dist/services/config/configAccessors.js +149 -0
- package/dist/services/config/index.d.ts +2 -0
- package/dist/services/config/index.d.ts.map +1 -0
- package/dist/services/config/index.js +1 -0
- package/dist/services/errors.d.ts +72 -0
- package/dist/services/errors.d.ts.map +1 -0
- package/dist/services/errors.js +31 -0
- package/dist/services/index.d.ts +7 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +6 -0
- package/dist/services/network/NodeReadinessService.d.ts +35 -0
- package/dist/services/network/NodeReadinessService.d.ts.map +1 -0
- package/dist/services/network/NodeReadinessService.js +120 -0
- package/dist/services/network/PortDiscoveryService.d.ts +22 -0
- package/dist/services/network/PortDiscoveryService.d.ts.map +1 -0
- package/dist/services/network/PortDiscoveryService.js +77 -0
- package/dist/services/network/RpcPortDiscoveryService.d.ts +25 -0
- package/dist/services/network/RpcPortDiscoveryService.d.ts.map +1 -0
- package/dist/services/network/RpcPortDiscoveryService.js +136 -0
- package/dist/services/network/index.d.ts +4 -0
- package/dist/services/network/index.d.ts.map +1 -0
- package/dist/services/network/index.js +3 -0
- package/dist/services/process/ProcessManagerService.d.ts +49 -0
- package/dist/services/process/ProcessManagerService.d.ts.map +1 -0
- package/dist/services/process/ProcessManagerService.js +162 -0
- package/dist/services/process/index.d.ts +3 -0
- package/dist/services/process/index.d.ts.map +1 -0
- package/dist/services/process/index.js +2 -0
- package/dist/services/process/launchNodeEffect.d.ts +40 -0
- package/dist/services/process/launchNodeEffect.d.ts.map +1 -0
- package/dist/services/process/launchNodeEffect.js +86 -0
- package/dist/util/functions/index.d.ts +3 -0
- package/dist/util/functions/index.d.ts.map +1 -0
- package/dist/util/functions/index.js +4 -0
- package/dist/util/index.d.ts +4 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +2 -0
- package/package.json +157 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ApiPromise } from "@polkadot/api";
|
|
2
|
+
import { setupLogger as createTestLogger } from "./logger.js";
|
|
3
|
+
export declare const setupLogger: typeof createTestLogger;
|
|
4
|
+
export declare function log(...msg: any[]): void;
|
|
5
|
+
export declare const printTokens: (api: ApiPromise, tokens: bigint, decimals?: number, pad?: number) => string;
|
|
6
|
+
export declare const printEvents: (api: ApiPromise, hash?: string) => Promise<void>;
|
|
7
|
+
//# sourceMappingURL=logging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../src/internal/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,oBAAoB;AAG9D,eAAO,MAAM,WAAW,yBAAmB,CAAC;AAE5C,wBAAgB,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,QAIhC;AAED,eAAO,MAAM,WAAW,GAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,EAAE,iBAAY,EAAE,YAAO,WAWjF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,KAAK,UAAU,EAAE,OAAO,MAAM,kBA2B/D,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { mapExtrinsics } from "../api/testing/blocks.js";
|
|
2
|
+
import { setupLogger as createTestLogger } from "./logger.js";
|
|
3
|
+
// Re-export setupLogger from logger.ts for backward compatibility
|
|
4
|
+
export const setupLogger = createTestLogger;
|
|
5
|
+
export function log(...msg) {
|
|
6
|
+
if (process.argv?.[2] && process.argv[2] === "--printlogs") {
|
|
7
|
+
console.log(...msg);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export const printTokens = (api, tokens, decimals = 2, pad = 9) => {
|
|
11
|
+
if (!api.registry.chainDecimals[0]) {
|
|
12
|
+
throw new Error("Chain decimals not found for system token");
|
|
13
|
+
}
|
|
14
|
+
return `${(Math.ceil(Number(tokens / 10n ** BigInt(api.registry.chainDecimals[0] - decimals))) /
|
|
15
|
+
10 ** decimals)
|
|
16
|
+
.toString()
|
|
17
|
+
.padStart(pad)} ${api.registry.chainTokens[0]}`;
|
|
18
|
+
};
|
|
19
|
+
export const printEvents = async (api, hash) => {
|
|
20
|
+
const blockHash = hash || (await api.rpc.chain.getBlockHash()).toString();
|
|
21
|
+
const apiAt = await api.at(blockHash);
|
|
22
|
+
const { block } = await api.rpc.chain.getBlock(blockHash);
|
|
23
|
+
const allRecords = (await apiAt.query.system.events());
|
|
24
|
+
const txsWithEvents = mapExtrinsics(block.extrinsics, allRecords);
|
|
25
|
+
console.log(`===== Block #${block.header.number.toString()}: ${blockHash}`);
|
|
26
|
+
console.log(block.header.toHuman());
|
|
27
|
+
console.log(txsWithEvents
|
|
28
|
+
.map(({ extrinsic, events }, i) => ` [${i}]: ${extrinsic.method.section.toString()}. ` +
|
|
29
|
+
`${extrinsic.method.method.toString()}\n` +
|
|
30
|
+
` - 0x${Buffer.from(extrinsic.data).toString("hex")}\n${events
|
|
31
|
+
.map((event) => ` * ${event.section.toString()}.${event.method.toString()}:\n${event.data
|
|
32
|
+
.map((datum) => ` - ${datum.toHex()}`)
|
|
33
|
+
.join("\n")}`)
|
|
34
|
+
.join("\n")}`)
|
|
35
|
+
.join("\n"));
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moondebug.d.ts","sourceRoot":"","sources":["../src/moondebug.ts"],"names":[],"mappings":";AACA,kCAAkC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-process file lock with staleness detection.
|
|
3
|
+
* Uses atomic mkdir + PID/timestamp metadata to prevent deadlocks.
|
|
4
|
+
*/
|
|
5
|
+
import { FileSystem } from "@effect/platform";
|
|
6
|
+
import { Duration, Effect } from "effect";
|
|
7
|
+
import { FileLockError } from "../errors.js";
|
|
8
|
+
export declare const acquireFileLock: (lockPath: string, timeout?: Duration.Duration) => Effect.Effect<void, FileLockError, FileSystem.FileSystem>;
|
|
9
|
+
export declare const releaseFileLock: (lockPath: string) => Effect.Effect<void, never, FileSystem.FileSystem>;
|
|
10
|
+
export declare const withFileLock: <A, E, R>(lockPath: string, effect: Effect.Effect<A, E, R>, timeout?: Duration.Duration) => Effect.Effect<A, E | FileLockError, R | FileSystem.FileSystem>;
|
|
11
|
+
//# sourceMappingURL=FileLock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileLock.d.ts","sourceRoot":"","sources":["../../../src/services/cache/FileLock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAY,MAAM,QAAQ,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,qBAAqB;AA+E7C,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,2BAA6B,KAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,UAAU,CAIxD,CAAC;AAEJ,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAI/C,CAAC;AAEL,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAClC,UAAU,MAAM,EAChB,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,2BAA6B,KAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,CAK7D,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-process file lock with staleness detection.
|
|
3
|
+
* Uses atomic mkdir + PID/timestamp metadata to prevent deadlocks.
|
|
4
|
+
*/
|
|
5
|
+
import { FileSystem } from "@effect/platform";
|
|
6
|
+
import { Duration, Effect, Schedule } from "effect";
|
|
7
|
+
import * as os from "node:os";
|
|
8
|
+
import { FileLockError } from "../errors.js";
|
|
9
|
+
const LOCK_MAX_AGE = Duration.minutes(2);
|
|
10
|
+
const LOCK_POLL_INTERVAL = Duration.millis(500);
|
|
11
|
+
const isProcessAlive = (pid) => Effect.try(() => {
|
|
12
|
+
process.kill(pid, 0);
|
|
13
|
+
return true;
|
|
14
|
+
}).pipe(Effect.orElseSucceed(() => false));
|
|
15
|
+
const isLockStale = (info) => Effect.gen(function* () {
|
|
16
|
+
const isTimedOut = Date.now() - info.timestamp > Duration.toMillis(LOCK_MAX_AGE);
|
|
17
|
+
if (isTimedOut)
|
|
18
|
+
return true;
|
|
19
|
+
const isSameHost = info.hostname === os.hostname();
|
|
20
|
+
if (!isSameHost)
|
|
21
|
+
return false;
|
|
22
|
+
const alive = yield* isProcessAlive(info.pid);
|
|
23
|
+
return !alive;
|
|
24
|
+
});
|
|
25
|
+
const cleanupStaleLock = (lockPath) => Effect.gen(function* () {
|
|
26
|
+
const fs = yield* FileSystem.FileSystem;
|
|
27
|
+
const infoPath = `${lockPath}/lock.json`;
|
|
28
|
+
const exists = yield* fs.exists(infoPath).pipe(Effect.orElseSucceed(() => false));
|
|
29
|
+
if (!exists)
|
|
30
|
+
return;
|
|
31
|
+
const content = yield* fs.readFileString(infoPath).pipe(Effect.orElseSucceed(() => ""));
|
|
32
|
+
const info = yield* Effect.try(() => JSON.parse(content)).pipe(Effect.orElseSucceed(() => null));
|
|
33
|
+
if (!info)
|
|
34
|
+
return;
|
|
35
|
+
const stale = yield* isLockStale(info);
|
|
36
|
+
if (stale) {
|
|
37
|
+
yield* fs.remove(lockPath, { recursive: true }).pipe(Effect.ignore);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const writeLockInfo = (lockPath) => Effect.gen(function* () {
|
|
41
|
+
const fs = yield* FileSystem.FileSystem;
|
|
42
|
+
const info = {
|
|
43
|
+
pid: process.pid,
|
|
44
|
+
timestamp: Date.now(),
|
|
45
|
+
hostname: os.hostname(),
|
|
46
|
+
};
|
|
47
|
+
yield* fs.writeFileString(`${lockPath}/lock.json`, JSON.stringify(info)).pipe(Effect.ignore);
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Single attempt to acquire lock - fails if lock exists
|
|
51
|
+
*/
|
|
52
|
+
const tryAcquireLock = (lockPath) => Effect.gen(function* () {
|
|
53
|
+
const fs = yield* FileSystem.FileSystem;
|
|
54
|
+
// Clean up stale locks before attempting
|
|
55
|
+
yield* cleanupStaleLock(lockPath);
|
|
56
|
+
// Atomic directory creation - fails if exists
|
|
57
|
+
yield* fs
|
|
58
|
+
.makeDirectory(lockPath)
|
|
59
|
+
.pipe(Effect.mapError(() => new FileLockError({ reason: "acquisition_failed", lockPath })));
|
|
60
|
+
// Write lock metadata
|
|
61
|
+
yield* writeLockInfo(lockPath);
|
|
62
|
+
});
|
|
63
|
+
export const acquireFileLock = (lockPath, timeout = Duration.minutes(2)) => tryAcquireLock(lockPath).pipe(Effect.retry(Schedule.fixed(LOCK_POLL_INTERVAL).pipe(Schedule.upTo(timeout))), Effect.catchAll(() => Effect.fail(new FileLockError({ reason: "timeout", lockPath }))));
|
|
64
|
+
export const releaseFileLock = (lockPath) => Effect.gen(function* () {
|
|
65
|
+
const fs = yield* FileSystem.FileSystem;
|
|
66
|
+
yield* fs.remove(lockPath, { recursive: true }).pipe(Effect.ignore);
|
|
67
|
+
});
|
|
68
|
+
export const withFileLock = (lockPath, effect, timeout = Duration.minutes(2)) => Effect.acquireUseRelease(acquireFileLock(lockPath, timeout), () => effect, () => releaseFileLock(lockPath));
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { StartupCacheError } from "../errors.js";
|
|
3
|
+
export interface StartupCacheConfig {
|
|
4
|
+
readonly binPath: string;
|
|
5
|
+
readonly chainArg?: string;
|
|
6
|
+
readonly cacheDir: string;
|
|
7
|
+
readonly generateRawChainSpec?: boolean;
|
|
8
|
+
readonly isDevMode?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface StartupCacheResult {
|
|
11
|
+
readonly precompiledPath: string;
|
|
12
|
+
readonly fromCache: boolean;
|
|
13
|
+
readonly rawChainSpecPath?: string;
|
|
14
|
+
}
|
|
15
|
+
declare const StartupCacheService_base: Context.TagClass<StartupCacheService, "StartupCacheService", {
|
|
16
|
+
readonly getCachedArtifacts: (config: StartupCacheConfig) => Effect.Effect<StartupCacheResult, StartupCacheError>;
|
|
17
|
+
}>;
|
|
18
|
+
export declare class StartupCacheService extends StartupCacheService_base {
|
|
19
|
+
}
|
|
20
|
+
export declare const StartupCacheServiceLive: Layer.Layer<StartupCacheService, never, never>;
|
|
21
|
+
export declare const StartupCacheServiceTestable: Layer.Layer<StartupCacheService, never, never>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=StartupCacheService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StartupCacheService.d.ts","sourceRoot":"","sources":["../../../src/services/cache/StartupCacheService.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAY,MAAM,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAC;AAE1E,OAAO,EAAE,iBAAiB,EAAsB,qBAAqB;AAKrE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;;iCAKgC,CAC3B,MAAM,EAAE,kBAAkB,KACvB,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;;AAL7D,qBAAa,mBAAoB,SAAQ,wBAOtC;CAAG;AAwPN,eAAO,MAAM,uBAAuB,gDAQlC,CAAC;AAEH,eAAO,MAAM,2BAA2B,gDAOtC,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Command, FileSystem, Path } from "@effect/platform";
|
|
2
|
+
import { NodeContext } from "@effect/platform-node";
|
|
3
|
+
import { createLogger } from "../../util/index.js";
|
|
4
|
+
import { Context, Duration, Effect, Layer, Option, Stream } from "effect";
|
|
5
|
+
import * as crypto from "node:crypto";
|
|
6
|
+
import { StartupCacheError } from "../errors.js";
|
|
7
|
+
import { withFileLock } from "./FileLock.js";
|
|
8
|
+
const logger = createLogger({ name: "StartupCacheService" });
|
|
9
|
+
export class StartupCacheService extends Context.Tag("StartupCacheService")() {
|
|
10
|
+
}
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Helper functions
|
|
13
|
+
// =============================================================================
|
|
14
|
+
const hashFile = (filePath) => Effect.gen(function* () {
|
|
15
|
+
const fs = yield* FileSystem.FileSystem;
|
|
16
|
+
const hash = crypto.createHash("sha256");
|
|
17
|
+
yield* fs
|
|
18
|
+
.stream(filePath)
|
|
19
|
+
.pipe(Stream.runForEach((chunk) => Effect.sync(() => hash.update(chunk))));
|
|
20
|
+
return hash.digest("hex");
|
|
21
|
+
}).pipe(Effect.mapError((cause) => new StartupCacheError({ cause, operation: "hash" })));
|
|
22
|
+
const findPrecompiledWasm = (dir) => Effect.gen(function* () {
|
|
23
|
+
const fs = yield* FileSystem.FileSystem;
|
|
24
|
+
const pathService = yield* Path.Path;
|
|
25
|
+
const exists = yield* fs.exists(dir);
|
|
26
|
+
if (!exists)
|
|
27
|
+
return Option.none();
|
|
28
|
+
const files = yield* fs.readDirectory(dir).pipe(Effect.orElseSucceed(() => []));
|
|
29
|
+
const wasmFile = files.find((f) => f.startsWith("precompiled_wasm_") || f.endsWith(".cwasm") || f.endsWith(".wasm"));
|
|
30
|
+
return wasmFile ? Option.some(pathService.join(dir, wasmFile)) : Option.none();
|
|
31
|
+
}).pipe(Effect.catchAll(() => Effect.succeed(Option.none())));
|
|
32
|
+
const checkCache = (cacheDir, hashPath, expectedHash) => Effect.gen(function* () {
|
|
33
|
+
const fs = yield* FileSystem.FileSystem;
|
|
34
|
+
const savedHash = yield* fs.readFileString(hashPath).pipe(Effect.orElseSucceed(() => ""));
|
|
35
|
+
if (savedHash.trim() !== expectedHash)
|
|
36
|
+
return Option.none();
|
|
37
|
+
const wasmPath = yield* findPrecompiledWasm(cacheDir);
|
|
38
|
+
if (Option.isNone(wasmPath))
|
|
39
|
+
return Option.none();
|
|
40
|
+
const accessible = yield* fs.access(wasmPath.value).pipe(Effect.as(true), Effect.orElseSucceed(() => false));
|
|
41
|
+
return accessible ? wasmPath : Option.none();
|
|
42
|
+
});
|
|
43
|
+
// =============================================================================
|
|
44
|
+
// Precompilation commands
|
|
45
|
+
// =============================================================================
|
|
46
|
+
const runPrecompile = (binPath, chainArg, outputDir) => Effect.gen(function* () {
|
|
47
|
+
const fs = yield* FileSystem.FileSystem;
|
|
48
|
+
const pathService = yield* Path.Path;
|
|
49
|
+
const args = chainArg
|
|
50
|
+
? ["precompile-wasm", chainArg, outputDir]
|
|
51
|
+
: ["precompile-wasm", outputDir];
|
|
52
|
+
logger.debug(`Precompiling: ${binPath} ${args.join(" ")}`);
|
|
53
|
+
const startTime = Date.now();
|
|
54
|
+
const exitCode = yield* Command.exitCode(Command.make(binPath, ...args)).pipe(Effect.mapError((e) => new StartupCacheError({ cause: e, operation: "precompile" })));
|
|
55
|
+
const files = yield* fs
|
|
56
|
+
.readDirectory(outputDir)
|
|
57
|
+
.pipe(Effect.mapError((e) => new StartupCacheError({ cause: e, operation: "precompile" })));
|
|
58
|
+
const wasmFile = files.find((f) => f.startsWith("precompiled_wasm_") || f.endsWith(".cwasm") || f.endsWith(".wasm"));
|
|
59
|
+
if (!wasmFile) {
|
|
60
|
+
return yield* Effect.fail(new StartupCacheError({
|
|
61
|
+
cause: `precompile-wasm failed (code ${exitCode}): no WASM file generated`,
|
|
62
|
+
operation: "precompile",
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
const wasmPath = pathService.join(outputDir, wasmFile);
|
|
66
|
+
logger.debug(`Precompiled in ${Date.now() - startTime}ms: ${wasmPath}`);
|
|
67
|
+
return wasmPath;
|
|
68
|
+
});
|
|
69
|
+
const generateRawChainSpec = (binPath, chainName, outputPath) => Effect.gen(function* () {
|
|
70
|
+
const fs = yield* FileSystem.FileSystem;
|
|
71
|
+
const args = chainName === "dev" || chainName === "default"
|
|
72
|
+
? ["build-spec", "--dev", "--raw"]
|
|
73
|
+
: ["build-spec", `--chain=${chainName}`, "--raw"];
|
|
74
|
+
logger.debug(`Generating raw chain spec: ${binPath} ${args.join(" ")}`);
|
|
75
|
+
const stdout = yield* Command.string(Command.make(binPath, ...args)).pipe(Effect.mapError((e) => new StartupCacheError({ cause: e, operation: "chainspec" })));
|
|
76
|
+
if (!stdout.length) {
|
|
77
|
+
return yield* Effect.fail(new StartupCacheError({ cause: "build-spec produced no output", operation: "chainspec" }));
|
|
78
|
+
}
|
|
79
|
+
yield* fs
|
|
80
|
+
.writeFileString(outputPath, stdout)
|
|
81
|
+
.pipe(Effect.mapError((e) => new StartupCacheError({ cause: e, operation: "chainspec" })));
|
|
82
|
+
return outputPath;
|
|
83
|
+
});
|
|
84
|
+
const maybeGetRawChainSpec = (binPath, chainName, cacheSubDir, shouldGenerate) => Effect.gen(function* () {
|
|
85
|
+
if (!shouldGenerate)
|
|
86
|
+
return Option.none();
|
|
87
|
+
const fs = yield* FileSystem.FileSystem;
|
|
88
|
+
const pathService = yield* Path.Path;
|
|
89
|
+
const rawSpecPath = pathService.join(cacheSubDir, `${chainName}-raw.json`);
|
|
90
|
+
const exists = yield* fs.exists(rawSpecPath).pipe(Effect.orElseSucceed(() => false));
|
|
91
|
+
if (exists)
|
|
92
|
+
return Option.some(rawSpecPath);
|
|
93
|
+
return yield* generateRawChainSpec(binPath, chainName, rawSpecPath).pipe(Effect.map((Option.some)), Effect.catchAll(() => Effect.succeed(Option.none())));
|
|
94
|
+
});
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// Main implementation
|
|
97
|
+
// =============================================================================
|
|
98
|
+
const getCachedArtifactsImpl = (config) => Effect.gen(function* () {
|
|
99
|
+
const fs = yield* FileSystem.FileSystem;
|
|
100
|
+
const pathService = yield* Path.Path;
|
|
101
|
+
const binaryHash = yield* hashFile(config.binPath);
|
|
102
|
+
const shortHash = binaryHash.substring(0, 12);
|
|
103
|
+
const chainName = config.isDevMode
|
|
104
|
+
? "dev"
|
|
105
|
+
: config.chainArg?.match(/--chain[=\s]?(\S+)/)?.[1] || "default";
|
|
106
|
+
const binName = pathService.basename(config.binPath);
|
|
107
|
+
const cacheSubDir = pathService.join(config.cacheDir, `${binName}-${chainName}-${shortHash}`);
|
|
108
|
+
const hashPath = pathService.join(cacheSubDir, "binary.hash");
|
|
109
|
+
const lockPath = pathService.join(config.cacheDir, `${binName}-${chainName}.lock`);
|
|
110
|
+
yield* fs
|
|
111
|
+
.makeDirectory(cacheSubDir, { recursive: true })
|
|
112
|
+
.pipe(Effect.mapError((e) => new StartupCacheError({ cause: e, operation: "cache" })));
|
|
113
|
+
// Fast path: cache exists
|
|
114
|
+
const cached = yield* checkCache(cacheSubDir, hashPath, binaryHash);
|
|
115
|
+
if (Option.isSome(cached)) {
|
|
116
|
+
logger.debug(`Using cached precompiled WASM: ${cached.value}`);
|
|
117
|
+
const rawChainSpecPath = yield* maybeGetRawChainSpec(config.binPath, chainName, cacheSubDir, config.generateRawChainSpec ?? false);
|
|
118
|
+
return {
|
|
119
|
+
precompiledPath: cached.value,
|
|
120
|
+
fromCache: true,
|
|
121
|
+
rawChainSpecPath: Option.getOrUndefined(rawChainSpecPath),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// Need to build - acquire lock using shared FileLock module
|
|
125
|
+
return yield* withFileLock(lockPath, Effect.gen(function* () {
|
|
126
|
+
// Double-check after acquiring lock
|
|
127
|
+
const nowCached = yield* checkCache(cacheSubDir, hashPath, binaryHash);
|
|
128
|
+
if (Option.isSome(nowCached)) {
|
|
129
|
+
logger.debug(`Using cached precompiled WASM (created by another process): ${nowCached.value}`);
|
|
130
|
+
const rawChainSpecPath = yield* maybeGetRawChainSpec(config.binPath, chainName, cacheSubDir, config.generateRawChainSpec ?? false);
|
|
131
|
+
return {
|
|
132
|
+
precompiledPath: nowCached.value,
|
|
133
|
+
fromCache: true,
|
|
134
|
+
rawChainSpecPath: Option.getOrUndefined(rawChainSpecPath),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Build
|
|
138
|
+
logger.debug("Precompiling WASM (this may take a moment)...");
|
|
139
|
+
const wasmPath = yield* runPrecompile(config.binPath, config.chainArg, cacheSubDir);
|
|
140
|
+
yield* fs
|
|
141
|
+
.writeFileString(hashPath, binaryHash)
|
|
142
|
+
.pipe(Effect.mapError((e) => new StartupCacheError({ cause: e, operation: "cache" })));
|
|
143
|
+
const rawChainSpecPath = yield* maybeGetRawChainSpec(config.binPath, chainName, cacheSubDir, config.generateRawChainSpec ?? false);
|
|
144
|
+
return {
|
|
145
|
+
precompiledPath: wasmPath,
|
|
146
|
+
fromCache: false,
|
|
147
|
+
rawChainSpecPath: Option.getOrUndefined(rawChainSpecPath),
|
|
148
|
+
};
|
|
149
|
+
}), Duration.minutes(2));
|
|
150
|
+
});
|
|
151
|
+
// =============================================================================
|
|
152
|
+
// Service Layer
|
|
153
|
+
// =============================================================================
|
|
154
|
+
export const StartupCacheServiceLive = Layer.succeed(StartupCacheService, {
|
|
155
|
+
getCachedArtifacts: (config) => getCachedArtifactsImpl(config).pipe(Effect.mapError((e) => e._tag === "FileLockError" ? new StartupCacheError({ cause: e, operation: "lock" }) : e), Effect.provide(NodeContext.layer)),
|
|
156
|
+
});
|
|
157
|
+
export const StartupCacheServiceTestable = Layer.succeed(StartupCacheService, {
|
|
158
|
+
getCachedArtifacts: (config) => getCachedArtifactsImpl(config).pipe(Effect.mapError((e) => e._tag === "FileLockError" ? new StartupCacheError({ cause: e, operation: "lock" }) : e)),
|
|
159
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/cache/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,yCAAyC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-chain Chopsticks support for XCM testing
|
|
3
|
+
*
|
|
4
|
+
* This module provides Effect-based support for launching multiple chopsticks
|
|
5
|
+
* instances and coordinating XCM message passing between them.
|
|
6
|
+
*/
|
|
7
|
+
import { Context, Effect, Layer } from "effect";
|
|
8
|
+
import type { HexString } from "@polkadot/util/types";
|
|
9
|
+
import { type ChopsticksConfig, type BlockCreationResult, ChopsticksSetupError, ChopsticksXcmError, ChopsticksBlockError } from "./ChopsticksService.js";
|
|
10
|
+
import { type ChopsticksServiceImpl } from "./launchChopsticksEffect.js";
|
|
11
|
+
declare const ChopsticksOrchestrationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
12
|
+
readonly _tag: "ChopsticksOrchestrationError";
|
|
13
|
+
} & Readonly<A>;
|
|
14
|
+
/**
|
|
15
|
+
* Error thrown when multi-chain orchestration fails
|
|
16
|
+
*/
|
|
17
|
+
export declare class ChopsticksOrchestrationError extends ChopsticksOrchestrationError_base<{
|
|
18
|
+
readonly cause: unknown;
|
|
19
|
+
readonly chains: string[];
|
|
20
|
+
readonly operation: "setup" | "xcm" | "cleanup";
|
|
21
|
+
}> {
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Configuration for a relay chain
|
|
25
|
+
*/
|
|
26
|
+
export interface RelayChainConfig extends ChopsticksConfig {
|
|
27
|
+
readonly type: "relay";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Configuration for a parachain
|
|
31
|
+
*/
|
|
32
|
+
export interface ParachainConfig extends ChopsticksConfig {
|
|
33
|
+
readonly type: "parachain";
|
|
34
|
+
readonly paraId: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Configuration for multi-chain setup
|
|
38
|
+
*/
|
|
39
|
+
export interface MultiChainConfig {
|
|
40
|
+
readonly relay: RelayChainConfig;
|
|
41
|
+
readonly parachains: ParachainConfig[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Chain instance with its identifier
|
|
45
|
+
*/
|
|
46
|
+
export interface ChainInstance {
|
|
47
|
+
readonly service: ChopsticksServiceImpl;
|
|
48
|
+
readonly type: "relay" | "parachain";
|
|
49
|
+
readonly paraId?: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Multi-chain orchestration service
|
|
53
|
+
*/
|
|
54
|
+
export interface MultiChainService {
|
|
55
|
+
/** Access the relay chain */
|
|
56
|
+
readonly relay: ChopsticksServiceImpl;
|
|
57
|
+
/** Access a parachain by paraId */
|
|
58
|
+
readonly parachain: (paraId: number) => ChopsticksServiceImpl | undefined;
|
|
59
|
+
/** Get all chains */
|
|
60
|
+
readonly chains: Map<string, ChainInstance>;
|
|
61
|
+
/** Create blocks on all chains */
|
|
62
|
+
readonly createBlocksAll: () => Effect.Effect<Map<string, BlockCreationResult>, ChopsticksBlockError>;
|
|
63
|
+
/**
|
|
64
|
+
* Send UMP from parachain to relay
|
|
65
|
+
* (Upward Message Passing: parachain → relay)
|
|
66
|
+
*/
|
|
67
|
+
readonly sendUmp: (paraId: number, messages: HexString[]) => Effect.Effect<void, ChopsticksXcmError>;
|
|
68
|
+
/**
|
|
69
|
+
* Send DMP from relay to parachain
|
|
70
|
+
* (Downward Message Passing: relay → parachain)
|
|
71
|
+
*/
|
|
72
|
+
readonly sendDmp: (paraId: number, messages: Array<{
|
|
73
|
+
sentAt: number;
|
|
74
|
+
msg: HexString;
|
|
75
|
+
}>) => Effect.Effect<void, ChopsticksXcmError>;
|
|
76
|
+
/**
|
|
77
|
+
* Send HRMP between parachains
|
|
78
|
+
* (Horizontal Relay-routed Message Passing: parachain → parachain)
|
|
79
|
+
*/
|
|
80
|
+
readonly sendHrmp: (fromParaId: number, toParaId: number, messages: Array<{
|
|
81
|
+
sentAt: number;
|
|
82
|
+
data: HexString;
|
|
83
|
+
}>) => Effect.Effect<void, ChopsticksXcmError>;
|
|
84
|
+
/**
|
|
85
|
+
* Process XCM messages by creating blocks on all chains
|
|
86
|
+
* This advances all chains to process pending XCM messages
|
|
87
|
+
*/
|
|
88
|
+
readonly processXcm: () => Effect.Effect<void, ChopsticksBlockError>;
|
|
89
|
+
}
|
|
90
|
+
declare const ChopsticksMultiChainService_base: Context.TagClass<ChopsticksMultiChainService, "ChopsticksMultiChainService", MultiChainService>;
|
|
91
|
+
/**
|
|
92
|
+
* Service tag for multi-chain orchestration
|
|
93
|
+
*/
|
|
94
|
+
export declare class ChopsticksMultiChainService extends ChopsticksMultiChainService_base {
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Launch a multi-chain setup with manual cleanup
|
|
98
|
+
*
|
|
99
|
+
* @param config - Multi-chain configuration
|
|
100
|
+
* @returns Promise with multi-chain service and cleanup function
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const { service, cleanup } = await launchMultiChainEffect({
|
|
105
|
+
* relay: {
|
|
106
|
+
* type: "relay",
|
|
107
|
+
* endpoint: "wss://rpc.polkadot.io",
|
|
108
|
+
* port: 8000,
|
|
109
|
+
* },
|
|
110
|
+
* parachains: [
|
|
111
|
+
* {
|
|
112
|
+
* type: "parachain",
|
|
113
|
+
* paraId: 2000,
|
|
114
|
+
* endpoint: "wss://moonbeam.rpc.io",
|
|
115
|
+
* port: 8001,
|
|
116
|
+
* },
|
|
117
|
+
* ],
|
|
118
|
+
* });
|
|
119
|
+
*
|
|
120
|
+
* // Send XCM message
|
|
121
|
+
* await Effect.runPromise(service.sendUmp(2000, ["0x..."]));
|
|
122
|
+
*
|
|
123
|
+
* // Process messages
|
|
124
|
+
* await Effect.runPromise(service.processXcm());
|
|
125
|
+
*
|
|
126
|
+
* // Cleanup
|
|
127
|
+
* await cleanup();
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare function launchMultiChainEffect(config: MultiChainConfig): Promise<{
|
|
131
|
+
service: MultiChainService;
|
|
132
|
+
cleanup: () => Promise<void>;
|
|
133
|
+
}>;
|
|
134
|
+
/**
|
|
135
|
+
* Create a Layer for multi-chain setup
|
|
136
|
+
*
|
|
137
|
+
* @param config - Multi-chain configuration
|
|
138
|
+
* @returns Layer providing ChopsticksMultiChainService
|
|
139
|
+
*/
|
|
140
|
+
export declare const ChopsticksMultiChainLayer: (config: MultiChainConfig) => Layer.Layer<ChopsticksMultiChainService, ChopsticksSetupError | ChopsticksOrchestrationError>;
|
|
141
|
+
/**
|
|
142
|
+
* Helper to create a standard Polkadot + Moonbeam XCM testing setup
|
|
143
|
+
*
|
|
144
|
+
* @param relayPort - Port for relay chain (default: 8000)
|
|
145
|
+
* @param moonbeamPort - Port for Moonbeam parachain (default: 8001)
|
|
146
|
+
* @returns Multi-chain configuration
|
|
147
|
+
*/
|
|
148
|
+
export declare const createPolkadotMoonbeamConfig: (relayPort?: number, moonbeamPort?: number) => MultiChainConfig;
|
|
149
|
+
/**
|
|
150
|
+
* Helper to create a standard Kusama + Moonriver XCM testing setup
|
|
151
|
+
*
|
|
152
|
+
* @param relayPort - Port for relay chain (default: 8000)
|
|
153
|
+
* @param moonriverPort - Port for Moonriver parachain (default: 8001)
|
|
154
|
+
* @returns Multi-chain configuration
|
|
155
|
+
*/
|
|
156
|
+
export declare const createKusamaMoonriverConfig: (relayPort?: number, moonriverPort?: number) => MultiChainConfig;
|
|
157
|
+
export {};
|
|
158
|
+
//# sourceMappingURL=ChopsticksMultiChain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChopsticksMultiChain.d.ts","sourceRoot":"","sources":["../../../src/services/chopsticks/ChopsticksMultiChain.ts"],"names":[],"mappings":"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"}
|