UNPKG

@moonsong-labs/moonwall-cli

Version:

Testing framework for the Moon family of projects

118 lines (115 loc) 3.97 kB
import { MoonwallContext } from "./chunk-WICDGWJQ.js"; // src/lib/contextHelpers.ts import "@moonbeam-network/api-augment"; import { customWeb3Request, alith, createAndFinalizeBlock } from "@moonsong-labs/moonwall-util"; import { assert } from "vitest"; import Debug from "debug"; var debug = Debug("context"); async function createBlock(w3Api, pjsApi, transactions, options = {}) { assert( MoonwallContext.getContext().foundation == "dev", "createBlock should only be used on DevMode foundations" ); const results = []; const txs = transactions == void 0 ? [] : Array.isArray(transactions) ? transactions : [transactions]; for await (const call of txs) { if (typeof call == "string") { results.push({ type: "eth", hash: (await customWeb3Request(w3Api, "eth_sendRawTransaction", [call])).result }); } else if (call.isSigned) { const tx = pjsApi.tx(call); debug( `- Signed: ${tx.method.section}.${tx.method.method}(${tx.args.map((d) => d.toHuman()).join("; ")}) [ nonce: ${tx.nonce}]` ); results.push({ type: "sub", hash: (await call.send()).toString() }); } else { const tx = pjsApi.tx(call); debug( `- Unsigned: ${tx.method.section}.${tx.method.method}(${tx.args.map((d) => d.toHuman()).join("; ")}) [ nonce: ${tx.nonce}]` ); results.push({ type: "sub", hash: (await call.signAndSend(alith)).toString() }); } } const { parentHash, finalize } = options; const blockResult = await createAndFinalizeBlock(pjsApi, parentHash, finalize); if (results.length == 0) { return { block: blockResult, result: null }; } const allRecords = await (await pjsApi.at(blockResult.hash)).query.system.events(); const blockData = await pjsApi.rpc.chain.getBlock(blockResult.hash); const result = results.map((result2) => { const extrinsicIndex = result2.type == "eth" ? allRecords.find( ({ phase, event: { section, method, data } }) => phase.isApplyExtrinsic && section == "ethereum" && method == "Executed" && data[2].toString() == result2.hash )?.phase?.asApplyExtrinsic?.toNumber() : blockData.block.extrinsics.findIndex((ext) => ext.hash.toHex() == result2.hash); const events = allRecords.filter( ({ phase }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.toNumber() === extrinsicIndex ); const failure = extractError(events); return { extrinsic: extrinsicIndex >= 0 ? blockData.block.extrinsics[extrinsicIndex] : null, events, error: failure && (failure.isModule && pjsApi.registry.findMetaError(failure.asModule) || { name: failure.toString() }), successful: extrinsicIndex !== void 0 && !failure, hash: result2.hash }; }); if (results.find((r) => r.type == "eth")) { await new Promise((resolve) => setTimeout(resolve, 2)); } return { block: blockResult, result: Array.isArray(transactions) ? result : result[0] }; } function filterAndApply(events, section, methods, onFound) { return events.filter(({ event }) => section === event.section && methods.includes(event.method)).map((record) => onFound(record)); } function getDispatchError({ event: { data: [dispatchError] } }) { return dispatchError; } function getDispatchInfo({ event: { data, method } }) { return method === "ExtrinsicSuccess" ? data[0] : data[1]; } function extractError(events = []) { return filterAndApply(events, "system", ["ExtrinsicFailed"], getDispatchError)[0]; } function isExtrinsicSuccessful(events = []) { return filterAndApply(events, "system", ["ExtrinsicSuccess"], () => true).length > 0; } function extractInfo(events = []) { return filterAndApply( events, "system", ["ExtrinsicFailed", "ExtrinsicSuccess"], getDispatchInfo )[0]; } export { createBlock, filterAndApply, getDispatchError, extractError, isExtrinsicSuccessful, extractInfo };