@taqueria/plugin-flextesa
Version:
A plugin for Taqueria providing local sandbox capabilities built on Flextesa
661 lines (656 loc) • 26.9 kB
JavaScript
// index.ts
import { Option, Plugin, Task } from "@taqueria/node-sdk";
// proxy.ts
import {
execCmd,
getArch as getArch2,
NonEmptyString,
noop,
readJsonFile,
sendAsyncErr,
sendAsyncRes,
sendErr,
sendJsonRes,
spawnCmd,
stringToSHA256,
writeJsonFile
} from "@taqueria/node-sdk";
import { Config } from "@taqueria/node-sdk";
import { LoadedConfig, Protocol, SandboxAccountConfig } from "@taqueria/node-sdk/types";
import retry from "async-retry";
import { BigNumber } from "bignumber.js";
import { getPortPromise } from "portfinder";
import { last } from "rambda";
// tzkt-manager.ts
import { getArch } from "@taqueria/node-sdk";
var getTzKtDockerImages = (opts) => ({
postgres: `postgres:14.5-alpine`,
sync: `bakingbad/tzkt-sync:latest`,
api: `bakingbad/tzkt-api:latest`
});
var getTzKtContainerNames = async (sandboxName, parsedArgs) => {
const uniqueSandboxName = await getUniqueSandboxName(sandboxName, parsedArgs.projectDir);
return {
postgres: `taq-postgres-${uniqueSandboxName}`,
sync: `taq-tzkt-sync-${uniqueSandboxName}`,
api: `taq-tzkt-api-${uniqueSandboxName}`
};
};
var getTzKtContainerEnvironments = async (sandboxName, sandbox, opts) => {
const containerNames = await getTzKtContainerNames(sandboxName, opts);
const sandboxContainerName = await getContainerName(opts);
const connectionStringEnv = `ConnectionStrings__DefaultConnection="host=${containerNames.postgres};port=5432;database=sandbox_data;username=tzkt;password=${sandboxName};"`;
return {
postgres: `--env POSTGRES_PASSWORD=${sandboxName} --env POSTGRES_USER=tzkt`,
sync: `--env ${connectionStringEnv} --env TezosNode__Endpoint="http://${sandboxContainerName}:20000/" --env Protocols__Fallback="PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW"`,
api: `--env ${connectionStringEnv} --env Kestrel__Endpoints__Http__Url="http://*:5000" --env MaxAttemptsForMigrations=120`
};
};
var getTzKtStartCommands = async (sandboxName, sandbox, opts) => {
var _a, _b;
const pgPort = ((_a = sandbox.tzkt) == null ? void 0 : _a.postgresqlPort) ?? 5432;
const newPGPort = await getNewPortIfPortInUse(pgPort);
const apiPort = ((_b = sandbox.tzkt) == null ? void 0 : _b.apiPort) ?? 5e3;
const newAPIPort = await getNewPortIfPortInUse(apiPort);
if (newPGPort !== pgPort || newAPIPort !== apiPort) {
if (newPGPort !== pgPort) {
console.log(
`${pgPort} is already in use, ${newPGPort} will be used for postgresql in ${sandboxName} instead and .taq/config.json will be updated to reflect this.`
);
}
if (newAPIPort !== apiPort) {
console.log(
`${apiPort} is already in use, ${newAPIPort} will be used for TzKt API in ${sandboxName} instead and .taq/config.json will be updated to reflect this.`
);
}
await updateConfig(opts, (config) => {
var _a2;
const sandbox2 = (_a2 = config.sandbox) == null ? void 0 : _a2[sandboxName];
if (typeof sandbox2 === "string" || sandbox2 === void 0) {
return void 0;
}
const oldTzKt = (sandbox2 == null ? void 0 : sandbox2.tzkt) ?? {
disableAutostartWithSandbox: false,
apiPort: 5e3,
postgresqlPort: 5432
};
const updatedConfig = {
...config,
sandbox: {
...config.sandbox,
[sandboxName]: {
...sandbox2,
tzkt: {
...oldTzKt,
postgresqlPort: newPGPort,
apiPort: newAPIPort
}
}
}
};
return updatedConfig;
});
}
const containerNames = await getTzKtContainerNames(sandboxName, opts);
const arch = await getArch();
const images = getTzKtDockerImages(opts);
const environmentVariables = await getTzKtContainerEnvironments(sandboxName, sandbox, opts);
return {
postgres: `docker run --network sandbox_${sandboxName}_net --name ${containerNames.postgres} --rm --detach --platform ${arch} -p ${newPGPort}:5432 ${environmentVariables.postgres} ${images.postgres}`,
sync: `docker run --network sandbox_${sandboxName}_net --name ${containerNames.sync} --rm --detach --platform ${arch} ${environmentVariables.sync} ${images.sync}`,
api: `docker run --network sandbox_${sandboxName}_net --name ${containerNames.api} --rm --detach --platform ${arch} -p ${newAPIPort}:5000 ${environmentVariables.api} ${images.api}`
};
};
// docker.ts
import { getDockerImage } from "@taqueria/node-sdk";
var TAQ_FLEXTESA_IMAGE_ENV_VAR = "TAQ_FLEXTESA_IMAGE";
var getDefaultDockerImage = (opts) => `registry.gitlab.com/tezos/flextesa:018ac39a-run`;
var getImage = (opts) => getDockerImage(getDefaultDockerImage(opts), TAQ_FLEXTESA_IMAGE_ENV_VAR);
// proxy.ts
var { Url } = Protocol;
var getUniqueSandboxName = async (sandboxName, projectDir) => {
const hash = String(await stringToSHA256(sandboxName + projectDir));
return `${sandboxName.substring(0, 10)}-${hash.substring(0, 5)}`;
};
var getContainerName = async (parsedArgs) => {
const uniqueSandboxName = await getUniqueSandboxName(parsedArgs.sandboxName, parsedArgs.projectDir);
return `taq-flextesa-${uniqueSandboxName}`;
};
var getNewPortIfPortInUse = async (port) => {
const newPort = await getPortPromise({ port });
return newPort;
};
var replaceRpcUrlInConfig = async (newPort, oldUrl, sandboxName, opts) => {
await updateConfig(opts, (config) => {
const newUrl = oldUrl.replace(/:\d+/, ":" + newPort);
const sandbox = config.sandbox;
const sandboxConfig = sandbox ? sandbox[sandboxName] : void 0;
if (typeof sandboxConfig === "string" || sandboxConfig === void 0) {
return;
}
const updatedConfig = {
...config,
sandbox: {
...sandbox,
[sandboxName]: {
...sandboxConfig,
rpcUrl: newUrl
}
}
};
return updatedConfig;
});
};
var updateConfig = async (opts, update) => {
const config = await readJsonFile(opts.config.configFile);
const updatedConfig = update(config);
if (!updatedConfig) {
return;
}
await writeJsonFile(opts.config.configFile)(updatedConfig);
return config;
};
var getFlextesaAnnotations = (sandbox) => {
const defaults = {
baking: "enabled",
block_time: 1
};
const settings = {
...defaults,
...sandbox.annotations
};
if (!["enabled", "disabled"].includes(settings.baking)) {
return Promise.reject(
'The "baking" setting of a Flextesa Sandbox must to set to either "enabled" or "disabled".'
);
} else if (!Number.isInteger(settings.block_time)) {
return Promise.reject(
'The "block_time" setting of a Flextesa Sandbox must be an integer, and set to a value greater than 0.'
);
} else if (settings.block_time <= 0) {
return Promise.reject(
'The "block_time" setting of a Flextesa Sandbox must be set to a value greater than 0. If you are trying to disable baking, please set the "baking" setting to "disabled" instead.'
);
}
return Promise.resolve(settings);
};
var getBakingFlags = (sandbox) => getFlextesaAnnotations(sandbox).then((settings) => {
if (settings.baking === "enabled") {
return [
`--time-b ${settings.block_time}`,
``
];
} else if (settings.baking === "disabled") {
return [
"--no-baking",
`--time-b 1`
];
}
return [
"--no-baking",
`--time-b 1`
];
});
var getSupportedProtocolKinds = /* @__PURE__ */ (() => {
let protocols = [];
const getAll = (opts) => {
const image = getImage(opts);
return execCmd(`docker run --rm ${image} flextesa mini-net --protocol-kind=foobar`).catch((err) => {
const { stderr } = err;
const protocols2 = stderr.match(/'[A-Z][a-z]+'/gm) ?? [];
return Promise.resolve(protocols2.map((protocol) => protocol.replace(/'/gm, "")));
});
};
return async (opts) => {
if (protocols.length == 0) protocols = await getAll(opts);
return protocols ?? ["Alpha"];
};
})();
var getProtocolKind = (sandbox, opts) => getSupportedProtocolKinds(opts).then((protocols) => {
const validProtocols = protocols.filter((p) => p != "Alpha" && p != "Oxford");
if (!sandbox.protocol || sandbox.protocol.includes("lpha")) {
return last(validProtocols);
}
return validProtocols.reduce(
(retval, protocolKind) => {
if (retval) return retval;
const givenProtocolHash = sandbox.protocol.toLowerCase();
const testProtocol = protocolKind.toLowerCase().slice(0, 4);
return givenProtocolHash.includes(testProtocol) ? protocolKind : void 0;
},
void 0
) ?? last(validProtocols);
});
var getBootstrapBalance = (opts) => Object.values(opts.config.accounts || {}).reduce(
(retval, amount) => retval.plus(new BigNumber(amount.replaceAll("_", ""))),
new BigNumber(0).multipliedBy(1e6)
).multipliedBy(1e3);
var getMininetCommand = (sandboxName, sandbox, opts) => Promise.all([
// getAccountFlags(sandbox, opts.config),
getBakingFlags(sandbox),
getProtocolKind(sandbox, opts)
]).then(([bakingFlags, protocolKind]) => [
"flextesa mini-net",
"--root /tmp/mini-box",
"--set-history-mode N000:archive",
// TODO: Add annotation for this setting
"--until-level 200_000_000",
// TODO: Add annotation for this setting
`--number-of-b 1`,
`--protocol-kind="${protocolKind}"`,
"--size 1",
`--balance-of-bootstrap-accounts=mutez:${getBootstrapBalance(opts)}`,
// ...accountFlags,
...bakingFlags
]).then((flags) => flags.join(" "));
var getStartCommand = async (sandboxName, sandbox, opts) => {
const port = new URL(sandbox.rpcUrl).port;
const newPort = (await getNewPortIfPortInUse(parseInt(port))).toString();
if (newPort !== port) {
console.log(
`${port} is already in use, ${newPort} will be used for sandbox ${sandboxName} instead and .taq/config.json will be updated to reflect this.`
);
await replaceRpcUrlInConfig(newPort, sandbox.rpcUrl.toString(), sandboxName, opts);
}
const ports = `-p ${newPort}:20000 --expose 20000`;
const containerName = await getContainerName(opts);
const mininetCmd = await getMininetCommand(sandboxName, sandbox, opts);
const arch = await getArch2();
const image = getImage(opts);
const projectDir = process.env.PROJECT_DIR ?? opts.config.projectDir;
const proxyAbsPath = `${__dirname}/proxy.py`;
return `docker run -i --network sandbox_${sandboxName}_net --name ${containerName} --rm --detach --platform ${arch} ${ports} -v ${projectDir}:/project ${image} /bin/sh -c "flextesa_node_cors_origin=* ${mininetCmd}"`;
};
var startSandbox = (sandboxName, sandbox, opts) => {
if (doesNotUseFlextesa(sandbox)) {
return sendAsyncErr(`Cannot start ${sandbox.label} as its configured to use the ${sandbox.plugin} plugin.`);
}
return Promise.resolve(opts).then(addSandboxAccounts).then((loadedConfig) => {
console.log("Booting sandbox...");
return getStartCommand(sandboxName, sandbox, opts).then(execCmd).then(() => {
console.log("Importing accounts...");
return importSandboxAccounts(opts)(loadedConfig);
});
}).then(() => importBaker(opts)).then(() => configureTezosClient(sandboxName, opts)).then(() => {
console.log("Waiting for bootstrapping to complete...");
return waitForBootstrap(opts);
}).then(() => {
console.log("Funding declared accounts (please wait)...");
return new Promise((resolve) => setTimeout(resolve, 1e4)).then(() => fundDeclaredAccounts(opts));
}).then(() => {
console.log(`The sandbox "${sandboxName}" is ready.`);
});
};
var getConfigureCommand = async (opts) => {
const containerName = await getContainerName(opts);
return `docker exec -d ${containerName} octez-client --endpoint http://localhost:20000 config update`;
};
var doesUseFlextesa = (sandbox) => !sandbox.plugin || sandbox.plugin === "flextesa";
var doesNotUseFlextesa = (sandbox) => !doesUseFlextesa(sandbox);
var waitForBootstrap = (parsedArgs) => {
const sandbox = getValidSandbox(parsedArgs.sandboxName, parsedArgs.config);
const containerName = getContainerName(parsedArgs);
return getContainerName(parsedArgs).then((container) => execCmd(`docker exec ${container} octez-client bootstrapped`)).catch(({ stderr }) => {
if (stderr.includes("Failed to acquire the protocol version from the node")) return waitForBootstrap(parsedArgs);
throw stderr;
});
};
var createTransferList = (sandbox, parsedArgs) => {
const transferList = Object.keys(sandbox.accounts ?? {}).reduce(
(retval, accountName) => {
if (accountName === "default") return retval;
const balance = new BigNumber(parsedArgs.config.accounts[accountName].replaceAll("_", "")).div(1e6);
return [...retval, { destination: accountName, amount: balance.toString() }];
},
[]
);
return transferList;
};
var writeTransferList = (containerName, transferList) => {
const fileAbsPath = "/tmp/transferList.json";
const cmd = `docker cp ${fileAbsPath} ${containerName}:${fileAbsPath}`;
return writeJsonFile(fileAbsPath)(transferList).then(() => execCmd(cmd)).then(() => fileAbsPath);
};
var fundDeclaredAccounts = async (parsedArgs) => {
const sandbox = getValidSandbox(parsedArgs.sandboxName, parsedArgs.config);
const transferList = createTransferList(sandbox, parsedArgs);
try {
const containerName = await getContainerName(parsedArgs);
const transferListAbsPath = await writeTransferList(containerName, transferList);
const cmd = `docker exec ${containerName} octez-client multiple transfers from baker0 using ${transferListAbsPath} --burn-cap 1`;
const result = await execCmd(cmd);
return result;
} catch (e) {
if (parsedArgs.debug) console.warn(e);
return sendAsyncErr("Failed to fund declared accounts.");
}
};
var startContainer = async (container) => {
console.log(`Starting ${container.name}`);
try {
const result = await execCmd(container.command);
if (result.stderr) {
console.error(result.stderr);
}
console.log(result.stdout);
} catch (e) {
throw e;
}
};
var startInstance = async (sandboxName, sandbox, opts) => {
var _a;
await execCmd(
`docker network ls | grep 'sandbox_${sandboxName}_net' > /dev/null || docker network create --driver bridge sandbox_${sandboxName}_net`
);
const isRunning = await isSandboxRunning(opts.sandboxName, opts);
if (isRunning) {
await sendAsyncRes("Already running.");
return;
}
await startSandbox(sandboxName, sandbox, opts);
if (((_a = sandbox.tzkt) == null ? void 0 : _a.disableAutostartWithSandbox) === true) {
return;
}
const { postgres, sync, api } = await getTzKtStartCommands(sandboxName, sandbox, opts);
const tzKtContainers = [
{ name: "postgresql", command: postgres },
{ name: "TzKt.Sync", command: sync },
{ name: "TzKt.Api", command: api }
];
for (const container of tzKtContainers) {
await startContainer(container);
}
};
var configureTezosClient = (sandboxName, opts) => retry(
() => getConfigureCommand(opts).then(execCmd).then(({ stderr, stdout }) => {
if (stderr.length) return Promise.reject(stderr);
return { stderr, stdout };
})
);
var importBaker = (opts) => getContainerName(opts).then(
(container) => `docker exec -d ${container} octez-client import secret key baker0 unencrypted:edsk3RFgDiCt7tWB2oe96w1eRw72iYiiqZPLu9nnEY23MYRp2d8Kkx`
).then(execCmd);
var getSandbox = ({ sandboxName, config }) => {
if (sandboxName && config.sandbox && config.sandbox[sandboxName]) {
const sandboxConfig = config.sandbox[sandboxName];
return sandboxConfig;
}
return void 0;
};
var getValidSandbox = (sandboxName, config) => {
const retval = config.sandbox[sandboxName];
retval.rpcUrl = retval.rpcUrl && retval.rpcUrl.length > 0 ? retval.rpcUrl : Url.create("http://localhost:20000");
return retval;
};
var startSandboxTask = (parsedArgs) => {
const sandbox = getValidSandbox(parsedArgs.sandboxName, parsedArgs.config);
return sandbox ? startInstance(parsedArgs.sandboxName, sandbox, parsedArgs) : sendAsyncErr(`There is no sandbox configuration with the name ${parsedArgs.sandboxName}.`);
};
var isSandboxRunning = (sandboxName, opts) => {
return getContainerName(opts).then((containerName) => execCmd(`docker ps --filter name=${containerName} | grep -w ${containerName}`)).then((_) => true).catch((_) => false);
};
var getAccountBalances = (sandboxName, sandbox, opts) => {
const processes = Object.entries(sandbox.accounts ?? {}).reduce(
(retval, [accountName, accountDetails]) => {
if (accountName === "default") return retval;
const getBalanceProcess = getArch2().then((_) => getContainerName(opts)).then((containerName) => `docker exec ${containerName} octez-client get balance for ${accountName.trim()}`).then(execCmd).then(({ stdout, stderr }) => {
if (stderr.length > 0) sendErr(stderr);
return {
account: accountName,
balance: stdout.trim(),
address: accountDetails.publicKeyHash
};
}).catch((err) => {
sendErr(err.message);
return {
account: accountName,
balance: "Error",
address: accountDetails.publicKeyHash
};
});
return [...retval, getBalanceProcess];
},
[]
);
return Promise.all(processes);
};
var listAccountsTask = async (parsedArgs) => {
if (parsedArgs.sandboxName) {
const sandbox = getSandbox(parsedArgs);
if (sandbox) {
if (doesUseFlextesa(sandbox)) {
return await isSandboxRunning(parsedArgs.sandboxName, parsedArgs) ? getAccountBalances(parsedArgs.sandboxName, sandbox, parsedArgs).then(sendJsonRes) : sendAsyncErr(`The ${parsedArgs.sandboxName} sandbox is not running.`);
}
return sendAsyncErr(
`Cannot start ${sandbox.label} as its configured to use the ${sandbox.plugin} plugin.`
);
}
return sendAsyncErr(`There is no sandbox configuration with the name ${parsedArgs.sandboxName}.`);
}
return sendAsyncErr(`Please specify a sandbox. E.g. taq list accounts local`);
};
var stopSandboxTask = async (parsedArgs) => {
if (parsedArgs.sandboxName) {
const sandbox = getSandbox(parsedArgs);
if (sandbox) {
if (doesUseFlextesa(sandbox)) {
await isSandboxRunning(parsedArgs.sandboxName, parsedArgs) ? execCmd(`docker kill ${await getContainerName(parsedArgs)}`).then((_) => sendAsyncRes(`Stopped ${parsedArgs.sandboxName}.`)) : sendAsyncRes(`The ${parsedArgs.sandboxName} sandbox was not running.`);
await stopTzKtContainers(parsedArgs.sandboxName, sandbox, parsedArgs);
return;
}
return sendAsyncErr(`Cannot stop ${sandbox.label} as its configured to use the ${sandbox.plugin} plugin.`);
}
return sendAsyncErr(`There is no sandbox configuration with the name ${parsedArgs.sandboxName}.`);
}
return sendAsyncErr(`No sandbox specified`);
};
var restartSandboxTask = async (parsedArgs) => {
await stopSandboxTask(parsedArgs);
await startSandboxTask(parsedArgs);
};
var stopTzKtContainers = async (sandboxName, sandbox, parsedArgs) => {
const containerNames = await getTzKtContainerNames(sandboxName, parsedArgs);
const containersToStop = [containerNames.api, containerNames.sync, containerNames.postgres];
for (const container of containersToStop) {
try {
const result = await execCmd(`docker stop ${container}`);
if (result.stderr) {
console.error(result.stderr);
}
console.log(result.stdout);
} catch (e) {
}
}
};
var listProtocolsTask = (parsedArgs) => {
const image = getImage(parsedArgs);
const cmd = `docker run --rm ${image} octez-client -M mockup list mockup protocols 2>/dev/null`;
return execCmd(cmd).then(({ stdout }) => stdout.trim().split("\n").map((hash) => ({ "protocols": hash }))).then(sendJsonRes);
};
var bakeTask = (parsedArgs) => getContainerName(parsedArgs).then(async (containerName) => {
if (parsedArgs.watch) {
console.log("Baking on demand as operations are injected.");
console.log("Press CTRL-C to stop and exit.");
console.log();
while (true) {
console.log("Waiting for operations to be injected...");
while (true) {
const { stdout } = await execCmd(
`docker exec ${containerName} octez-client rpc get /chains/main/mempool/pending_operations`
);
const ops = JSON.parse(stdout);
if (Array.isArray(ops.applied) && ops.applied.length > 0 || Array.isArray(ops.validated) && ops.validated.length > 0) break;
}
await spawnCmd(`docker exec ${containerName} octez-client bake for baker0`);
noop();
}
}
return spawnCmd(`docker exec ${containerName} octez-client bake for baker0`).then(noop);
});
var instantiateAccounts = (parsedArgs) => {
console.log("Generating account keys...");
return Object.entries(parsedArgs.config.accounts).reduce(
(lastConfig, [accountName, _]) => (
// TODO: This could probably be more performant by generating the key pairs using TS rather than proxy to docker/flextesa
lastConfig.then((_2) => execCmd(`docker run --rm ${getImage(parsedArgs)} flextesa key ${accountName}`)).then((result) => result.stdout.trim().split(",")).then(
([_alias, encryptedKey, publicKeyHash, secretKey]) => SandboxAccountConfig.create({
encryptedKey,
publicKeyHash,
secretKey
})
).then(async (accountConfig) => {
const config = await lastConfig;
const accounts = config.sandbox[parsedArgs.sandboxName].accounts ?? { "default": NonEmptyString.create(accountName) };
accounts[accountName] = accountConfig;
config.sandbox[parsedArgs.sandboxName].accounts = accounts;
return config;
})
),
Promise.resolve(parsedArgs.config)
).then(Config.create).then((config) => writeJsonFile(parsedArgs.config.configFile)(config).then((_) => config)).then(
(config) => LoadedConfig.create({
...parsedArgs.config,
...config
})
);
};
var hasInstantiatedAccounts = (parsedArgs) => {
const sandbox = getValidSandbox(parsedArgs.sandboxName, parsedArgs.config);
const accounts = sandbox.accounts ?? {};
return Object.keys(accounts).length > 0;
};
var maybeInstantiateAccounts = (parsedArgs) => {
return hasInstantiatedAccounts(parsedArgs) ? Promise.resolve(parsedArgs.config) : instantiateAccounts(parsedArgs);
};
var importSandboxAccounts = (parsedArgs) => async (updatedConfig) => {
const containerName = await getContainerName(parsedArgs);
const cmds = Object.entries(getValidSandbox(parsedArgs.sandboxName, updatedConfig).accounts ?? {}).reduce(
(retval, [accountName, account]) => typeof account === "string" ? retval : [...retval, `octez-client import secret key ${accountName} ${account.secretKey} --force`],
[]
);
await execCmd(`docker exec -d ${containerName} sh -c '${cmds.join(" && ")}'`);
};
var addSandboxAccounts = (parsedArgs) => maybeInstantiateAccounts(parsedArgs);
var getDefaultSandboxName = (parsedArgs) => {
const env = parsedArgs.config.environment[parsedArgs.env];
if (env.sandboxes && env.sandboxes.length > 0) {
return env.sandboxes[0];
}
return void 0;
};
var taskMap = {
"list accounts": listAccountsTask,
"show protocols": listProtocolsTask,
"list protocols": listProtocolsTask,
"start sandbox": startSandboxTask,
"start flextesa": startSandboxTask,
"stop sandbox": stopSandboxTask,
"stop flextesa": stopSandboxTask,
"bake": bakeTask,
"b": bakeTask,
"restart sandbox": restartSandboxTask,
"restart flextesa": restartSandboxTask
};
var validateRequest = async (unparsedArgs) => {
const origSandboxName = unparsedArgs.sandboxName;
const sandboxName = unparsedArgs.sandboxName ?? getDefaultSandboxName(unparsedArgs);
const modifiedArgs = { ...unparsedArgs, sandboxName };
const sandbox = getSandbox(modifiedArgs);
if (!sandbox) {
return sendAsyncErr(
unparsedArgs.sandboxName ? `There is no sandbox called ${origSandboxName} in your .taq/config.json.` : `No sandbox name was specified. We couldn't find a valid sandbox config for the current environment.`
);
}
if (!unparsedArgs.task || !Object.keys(taskMap).includes(unparsedArgs.task)) {
return await sendAsyncErr(`${unparsedArgs.task} is not an understood task by the Flextesa plugin`);
}
if (doesNotUseFlextesa(sandbox)) {
return sendAsyncErr(
`Cannot ${unparsedArgs.task} for ${sandbox.label} as its configured to use the ${sandbox.plugin} plugin.`
);
}
if (!unparsedArgs.config.accounts || Object.keys(unparsedArgs.config.accounts).length === 0) {
return await sendAsyncErr(`This task required a list of declared accounts in your .taq/config.json.`);
}
return modifiedArgs;
};
var proxy = (unparsedArgs) => {
if (unparsedArgs.task && (unparsedArgs.task == "list protocols" || unparsedArgs.task === "show protocols")) {
return listProtocolsTask(unparsedArgs);
} else {
return validateRequest(unparsedArgs).then((modifiedArgs) => {
const parsedArgs = modifiedArgs;
return taskMap[parsedArgs.task](parsedArgs);
});
}
};
var proxy_default = proxy;
// index.ts
Plugin.create((_i18n) => ({
alias: "flextesa",
schema: "1.0",
version: "0.1",
tasks: [
Task.create({
task: "start sandbox",
command: "start sandbox",
aliases: ["start flextesa"],
description: "Starts a flextesa sandbox",
options: [],
handler: "proxy",
encoding: "none"
}),
Task.create({
task: "stop sandbox",
command: "stop sandbox",
aliases: ["stop flextesa"],
description: "Stops a flextesa sandbox",
options: [],
handler: "proxy"
}),
Task.create({
task: "restart sandbox",
command: "restart sandbox",
aliases: ["restart flextesa"],
description: "Restarts a flextesa sandbox",
options: [],
handler: "proxy"
}),
Task.create({
task: "list accounts",
command: "list accounts",
aliases: [],
description: "List the balances of all sandbox accounts",
options: [],
handler: "proxy",
encoding: "json"
}),
Task.create({
task: "bake",
command: "bake",
aliases: ["b"],
description: 'Manually bake a block. Use when the "baking" setting of a flextesa sandbox is set to "disabled".',
options: [
Option.create({
flag: "watch",
shortFlag: "w",
description: "Watch for operations as they are injected into the mempool and bake them as immediate as possible.",
boolean: true
})
],
handler: "proxy",
encoding: "none"
}),
Task.create({
task: "show protocols",
command: "show protocols",
aliases: ["list protocols"],
description: "List protocols understood by this version of Flextesa",
options: [],
handler: "proxy",
encoding: "json"
})
],
proxy: proxy_default
}), process.argv);
//# sourceMappingURL=index.mjs.map