diff --git a/README.md b/README.md index 51a6b4e4..6d707795 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ A newly generated project will have a `swanky.config.json` file that will get po "node": { "localPath": "/Users/sasapul/Work/astar/swanky-cli/temp_proj/bin/swanky-node", "polkadotPalletVersions": "polkadot-v0.9.39", - "supportedInk": "v4.2.0" + "supportedInk": "v4.3.0" }, "accounts": [ { diff --git a/src/commands/check/index.ts b/src/commands/check/index.ts index 9d1d27fa..a8604e95 100644 --- a/src/commands/check/index.ts +++ b/src/commands/check/index.ts @@ -1,14 +1,23 @@ import { Listr } from "listr2"; import { commandStdoutOrNull } from "../../lib/index.js"; import { SwankyConfig } from "../../types/index.js"; -import { pathExistsSync, readJSON } from "fs-extra/esm"; +import { pathExistsSync, readJSON, writeJson } from "fs-extra/esm"; import { readFileSync } from "fs"; import path from "node:path"; import TOML from "@iarna/toml"; import semver from "semver"; import { SwankyCommand } from "../../lib/swankyCommand.js"; +import { Flags } from "@oclif/core"; +import chalk from "chalk"; +import { CARGO_CONTRACT_INK_DEPS } from "../../lib/cargoContractInfo.js"; +import { CLIError } from "@oclif/core/lib/errors/index.js"; +import Warn = CLIError.Warn; interface Ctx { + os: { + platform: string; + architecture: string; + }, versions: { tools: { rust?: string | null; @@ -17,50 +26,117 @@ interface Ctx { cargoDylint?: string | null; cargoContract?: string | null; }; + supportedInk?: string; + missingTools: string[]; contracts: Record>; + swankyNode: string | null; }; swankyConfig?: SwankyConfig; - mismatchedVersions?: Record; + mismatchedVersions: Record; looseDefinitionDetected: boolean; } export default class Check extends SwankyCommand { static description = "Check installed package versions and compatibility"; + static flags = { + print: Flags.string({ + char: "o", + description: "File to write output to", + }), + }; + public async run(): Promise { + const { flags } = await this.parse(Check); + const swankyNodeVersion = this.swankyConfig.node.version; + const isSwankyNodeInstalled = !!swankyNodeVersion; + const anyContracts = Object.keys(this.swankyConfig?.contracts).length > 0; const tasks = new Listr([ + { + title: "Check OS", + task: async (ctx, task) => { + ctx.os.platform = process.platform; + ctx.os.architecture = process.arch; + const supportedPlatforms = ["darwin", "linux"]; + const supportedArch = ["arm64", "x64"]; + + if (!supportedPlatforms.includes(ctx.os.platform)) { + throw new Error(`Platform ${ctx.os.platform} is not supported`); + } + if (!supportedArch.includes(ctx.os.architecture)) { + throw new Error(`Architecture ${ctx.os.architecture} is not supported`); + } + + task.title = `Check OS: '${ctx.os.platform}-${ctx.os.architecture}'`; + }, + exitOnError: false, + }, { title: "Check Rust", - task: async (ctx) => { - ctx.versions.tools.rust = await commandStdoutOrNull("rustc --version"); + task: async (ctx, task) => { + ctx.versions.tools.rust = (await commandStdoutOrNull("rustc --version"))?.match(/rustc (.*) \((.*)/)?.[1]; + if (!ctx.versions.tools.rust) { + throw new Error("Rust is not installed"); + } + task.title = `Check Rust: ${ctx.versions.tools.rust}`; }, + exitOnError: false, }, { title: "Check cargo", - task: async (ctx) => { - ctx.versions.tools.cargo = await commandStdoutOrNull("cargo -V"); + task: async (ctx, task) => { + ctx.versions.tools.cargo = (await commandStdoutOrNull("cargo -V"))?.match(/cargo (.*) \((.*)/)?.[1]; + if (!ctx.versions.tools.cargo) { + throw new Error("Cargo is not installed"); + } + task.title = `Check cargo: ${ctx.versions.tools.cargo}`; }, + exitOnError: false, }, { title: "Check cargo nightly", - task: async (ctx) => { - ctx.versions.tools.cargoNightly = await commandStdoutOrNull("cargo +nightly -V"); + task: async (ctx, task) => { + ctx.versions.tools.cargoNightly = (await commandStdoutOrNull("cargo +nightly -V"))?.match(/cargo (.*)-nightly \((.*)/)?.[1]; + if (!ctx.versions.tools.cargoNightly) { + throw new Error("Cargo nightly is not installed"); + } + task.title = `Check cargo nightly: ${ctx.versions.tools.cargoNightly}`; }, + exitOnError: false, }, { title: "Check cargo dylint", - task: async (ctx) => { - ctx.versions.tools.cargoDylint = await commandStdoutOrNull("cargo dylint -V"); + task: async (ctx, task) => { + ctx.versions.tools.cargoDylint = (await commandStdoutOrNull("cargo dylint -V"))?.match(/cargo-dylint (.*)/)?.[1]; + if (!ctx.versions.tools.cargoDylint) { + throw new Warn("Cargo dylint is not installed"); + } + task.title = `Check cargo dylint: ${ctx.versions.tools.cargoDylint}`; }, + exitOnError: false, }, { title: "Check cargo-contract", - task: async (ctx) => { + task: async (ctx, task) => { ctx.versions.tools.cargoContract = await commandStdoutOrNull("cargo contract -V"); + if (!ctx.versions.tools.cargoContract) { + throw new Error("Cargo contract is not installed"); + } + + const regex = /cargo-contract-contract (\d+\.\d+\.\d+(?:-[\w.]+)?)(?:-unknown-[\w-]+)/; + const match = ctx.versions.tools.cargoContract.match(regex); + if (match?.[1]) { + ctx.versions.tools.cargoContract = match[1]; + } else { + throw new Error("Cargo contract version not found"); + } + task.title = `Check cargo-contract: ${ctx.versions.tools.cargoContract}`; }, + exitOnError: false, }, { title: "Read ink dependencies", + enabled: anyContracts, task: async (ctx) => { const swankyConfig = await readJSON("swanky.config.json"); ctx.swankyConfig = swankyConfig; @@ -79,7 +155,7 @@ export default class Check extends SwankyCommand { const cargoToml = TOML.parse(cargoTomlString); const inkDependencies = Object.entries(cargoToml.dependencies) - .filter((dependency) => dependency[0].includes("ink_")) + .filter((dependency) => dependency[0].includes("ink")) .map(([depName, depInfo]) => { const dependency = depInfo as Dependency; return [depName, dependency.version ?? dependency.tag]; @@ -89,43 +165,122 @@ export default class Check extends SwankyCommand { }, }, { - title: "Verify ink version", + title: "Verify ink version compatibility with Swanky node", + skip: (ctx) => Object.keys(ctx.versions.contracts).length === 0, + enabled: anyContracts && isSwankyNodeInstalled, task: async (ctx) => { - const supportedInk = ctx.swankyConfig?.node.supportedInk; - + const supportedInk = ctx.swankyConfig!.node.supportedInk; const mismatched: Record = {}; Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { Object.entries(inkPackages).forEach(([inkPackage, version]) => { - if (semver.gt(version, supportedInk!)) { + if (semver.gt(version, supportedInk)) { mismatched[ `${contract}-${inkPackage}` - ] = `Version of ${inkPackage} (${version}) in ${contract} is higher than supported ink version (${supportedInk})`; + ] = `Version of ${inkPackage} (${version}) in ${chalk.yellowBright(contract)} is higher than supported ink version (${supportedInk}) in current Swanky node version (${swankyNodeVersion}). A Swanky node update can fix this warning.`; } - if (!(version.startsWith("=") || version.startsWith("v"))) { + if (version.startsWith(">") || version.startsWith("<") || version.startsWith("^") || version.startsWith("~")) { ctx.looseDefinitionDetected = true; } }); }); ctx.mismatchedVersions = mismatched; + if (Object.entries(mismatched).length > 0) { + throw new Warn("Ink versions in contracts don't match the Swanky node's supported version."); + } }, + exitOnError: false, + }, + { + title: "Verify cargo contract compatibility", + skip: (ctx) => !ctx.versions.tools.cargoContract, + enabled: anyContracts, + task: async (ctx) => { + const cargoContractVersion = ctx.versions.tools.cargoContract!; + const dependencyIdx = CARGO_CONTRACT_INK_DEPS.findIndex((dep) => + semver.satisfies(cargoContractVersion.replace(/-.*$/, ""), `>=${dep.minCargoContractVersion}`) + ); + + if (dependencyIdx === -1) { + throw new Warn(`cargo-contract version ${cargoContractVersion} is not supported`); + } + + const validInkVersionRange = CARGO_CONTRACT_INK_DEPS[dependencyIdx].validInkVersionRange; + const minCargoContractVersion = dependencyIdx === 0 + ? CARGO_CONTRACT_INK_DEPS[dependencyIdx].minCargoContractVersion + : CARGO_CONTRACT_INK_DEPS[dependencyIdx - 1].minCargoContractVersion + + const mismatched: Record = {}; + Object.entries(ctx.versions.contracts).forEach(([contract, inkPackages]) => { + Object.entries(inkPackages).forEach(([inkPackage, version]) => { + if (!semver.satisfies(version, validInkVersionRange)) { + mismatched[ + `${contract}-${inkPackage}` + ] = `Version of ${inkPackage} (${version}) in ${chalk.yellowBright(contract)} requires cargo-contract version >=${minCargoContractVersion}, but version ${cargoContractVersion} is installed`; + } + }); + }); + + ctx.mismatchedVersions = { ...ctx.mismatchedVersions, ...mismatched }; + if (Object.entries(mismatched).length > 0) { + throw new Warn("cargo-contract version mismatch"); + } + }, + exitOnError: false, + }, + { + title: "Check for missing tools", + task: async (ctx) => { + const missingTools: string[] = []; + for (const [toolName, toolVersion] of Object.entries(ctx.versions.tools)) { + if (!toolVersion) { + missingTools.push(toolName); + if (toolName === "cargoDylint") this.warn("Cargo dylint is not installed"); + else this.error(`${toolName} is not installed`); + } + } + ctx.versions.missingTools = missingTools; + if (Object.entries(missingTools).length > 0) { + throw new Warn(`Missing tools: ${missingTools.join(", ")}`); + } + }, + exitOnError: false, }, ]); + const context = await tasks.run({ - versions: { tools: {}, contracts: {} }, + os: { platform: "", architecture: "" }, + versions: { + tools: {}, + missingTools: [], + contracts: {}, + swankyNode: swankyNodeVersion || null, + }, looseDefinitionDetected: false, + mismatchedVersions: {} }); - console.log(context.versions); - Object.values(context.mismatchedVersions as any).forEach((mismatch) => - console.error(`[ERROR] ${mismatch as string}`) - ); + + Object.values(context.mismatchedVersions).forEach((mismatch) => this.warn(mismatch)); + if (context.looseDefinitionDetected) { - console.log(`\n[WARNING]Some of the ink dependencies do not have a fixed version. + this.warn(`Some of the ink dependencies do not have a fixed version. This can lead to accidentally installing version higher than supported by the node. Please use "=" to install a fixed version (Example: "=3.0.1") `); } + + const output = { + ...context.os, + ...context.versions + } + + const filePath = flags.print; + if (filePath !== undefined) { + await this.spinner.runCommand(async () => { + writeJson(filePath, output, { spaces: 2 }); + }, `Writing output to file ${chalk.yellowBright(filePath)}`); + } } } diff --git a/src/commands/init/index.ts b/src/commands/init/index.ts index 45177372..e7141b40 100644 --- a/src/commands/init/index.ts +++ b/src/commands/init/index.ts @@ -6,7 +6,7 @@ import { execaCommand, execaCommandSync } from "execa"; import { paramCase, pascalCase, snakeCase } from "change-case"; import inquirer from "inquirer"; import TOML from "@iarna/toml"; -import { choice, email, name, pickTemplate } from "../../lib/prompts.js"; +import { choice, email, name, pickNodeVersion, pickTemplate } from "../../lib/prompts.js"; import { checkCliDependencies, copyCommonTemplateFiles, @@ -15,12 +15,11 @@ import { installDeps, ChainAccount, processTemplates, - swankyNode, - getTemplates, + getTemplates, swankyNodeVersions, } from "../../lib/index.js"; import { DEFAULT_ASTAR_NETWORK_URL, - DEFAULT_NETWORK_URL, + DEFAULT_NETWORK_URL, DEFAULT_NODE_INFO, DEFAULT_SHIBUYA_NETWORK_URL, DEFAULT_SHIDEN_NETWORK_URL, } from "../../lib/consts.js"; @@ -93,11 +92,13 @@ export class Init extends SwankyCommand { } projectPath = ""; + configBuilder: Partial = { node: { localPath: "", - polkadotPalletVersions: swankyNode.polkadotPalletVersions, - supportedInk: swankyNode.supportedInk, + polkadotPalletVersions: "", + supportedInk: "", + version: "", }, accounts: [], networks: { @@ -161,12 +162,28 @@ export class Init extends SwankyCommand { choice("useSwankyNode", "Do you want to download Swanky node?"), ]); if (useSwankyNode) { + const versions = Array.from(swankyNodeVersions.keys()); + let nodeVersion = DEFAULT_NODE_INFO.version; + await inquirer.prompt([ + pickNodeVersion(versions), + ]).then((answers) => { + nodeVersion = answers.version; + }); + + const nodeInfo = swankyNodeVersions.get(nodeVersion)!; + this.taskQueue.push({ task: downloadNode, - args: [this.projectPath, swankyNode, this.spinner], + args: [this.projectPath, nodeInfo, this.spinner], runningMessage: "Downloading Swanky node", - callback: (result) => - this.configBuilder.node ? (this.configBuilder.node.localPath = result) : null, + callback: (result) => { + this.configBuilder.node = { + supportedInk: nodeInfo.supportedInk, + polkadotPalletVersions: nodeInfo.polkadotPalletVersions, + version: nodeInfo.version, + localPath: result, + }; + } }); } } diff --git a/src/commands/node/install.ts b/src/commands/node/install.ts index 8d9beb5e..79beab3e 100644 --- a/src/commands/node/install.ts +++ b/src/commands/node/install.ts @@ -1,39 +1,68 @@ import { SwankyCommand } from "../../lib/swankyCommand.js"; -import { ux } from "@oclif/core"; -import { downloadNode, swankyNode } from "../../lib/index.js"; +import { Flags } from "@oclif/core"; +import { downloadNode, swankyNodeVersions } from "../../lib/index.js"; import path from "node:path"; import { writeJSON } from "fs-extra/esm"; +import inquirer from "inquirer"; +import { DEFAULT_NODE_INFO } from "../../lib/consts.js"; +import { choice, pickNodeVersion } from "../../lib/prompts.js"; +import { InputError } from "../../lib/errors.js"; export class InstallNode extends SwankyCommand { static description = "Install swanky node binary"; + static flags = { + "set-version": Flags.string({ + description: "Specify version of swanky node to install. \n List of supported versions: " + Array.from(swankyNodeVersions.keys()).join(", "), + required: false, + }), + } async run(): Promise { const { flags } = await this.parse(InstallNode); if (flags.verbose) { this.spinner.verbose = true; } + let nodeVersion= DEFAULT_NODE_INFO.version; + + if (flags["set-version"]) { + nodeVersion = flags["set-version"]; + if(!swankyNodeVersions.has(nodeVersion)) { + throw new InputError(`Version ${nodeVersion} is not supported.\n List of supported versions: ${Array.from(swankyNodeVersions.keys()).join(", ")}`); + } + } else { + const versions = Array.from(swankyNodeVersions.keys()); + await inquirer.prompt([ + pickNodeVersion(versions), + ]).then((answers) => { + nodeVersion = answers.version; + }); + } const projectPath = path.resolve(); if (this.swankyConfig.node.localPath !== "") { - const overwrite = await ux.confirm( - "Swanky node already installed. Do you want to overwrite it? (y/n)" - ); + const { overwrite } =await inquirer.prompt([ + choice("overwrite", "Swanky node already installed. Do you want to overwrite it?"), + ]); if (!overwrite) { return; } } + const nodeInfo = swankyNodeVersions.get(nodeVersion)!; + const taskResult = (await this.spinner.runCommand( - () => downloadNode(projectPath, swankyNode, this.spinner), + () => downloadNode(projectPath, nodeInfo, this.spinner), "Downloading Swanky node" )) as string; const nodePath = path.relative(projectPath, taskResult); + this.swankyConfig.node = { localPath: nodePath, - polkadotPalletVersions: swankyNode.polkadotPalletVersions, - supportedInk: swankyNode.supportedInk, + polkadotPalletVersions: nodeInfo.polkadotPalletVersions, + supportedInk: nodeInfo.supportedInk, + version: nodeInfo.version, }; await this.spinner.runCommand( diff --git a/src/commands/node/start.ts b/src/commands/node/start.ts index cb976870..e92e65e6 100644 --- a/src/commands/node/start.ts +++ b/src/commands/node/start.ts @@ -1,6 +1,7 @@ import { Flags } from "@oclif/core"; import { execaCommand } from "execa"; import { SwankyCommand } from "../../lib/swankyCommand.js"; +import semver from "semver"; export class StartNode extends SwankyCommand { static description = "Start a local node"; @@ -28,11 +29,15 @@ export class StartNode extends SwankyCommand { async run(): Promise { const { flags } = await this.parse(StartNode); + if (this.swankyConfig.node.version === "") { + this.log("Node is not installed"); + return; + } // Run persistent mode by default. non-persistent mode in case flag is provided. // Non-Persistent mode (`--dev`) allows all CORS origin, without `--dev`, users need to specify origins by `--rpc-cors`. await execaCommand( `${this.swankyConfig.node.localPath} \ - --finalize-delay-sec ${flags.finalizeDelaySec} \ + ${ semver.gte(this.swankyConfig.node.version, "1.6.0") ? `--finalize-delay-sec ${flags.finalizeDelaySec}` : ""} \ ${flags.tmp ? "--dev" : `--rpc-cors ${flags.rpcCors}`}`, { stdio: "inherit", diff --git a/src/commands/node/version.ts b/src/commands/node/version.ts new file mode 100644 index 00000000..a6937d09 --- /dev/null +++ b/src/commands/node/version.ts @@ -0,0 +1,12 @@ +import { SwankyCommand } from "../../lib/swankyCommand.js"; +export class NodeVersion extends SwankyCommand { + static description = "Show swanky node version"; + async run(): Promise { + if(this.swankyConfig.node.version === ""){ + this.log("Swanky node is not installed"); + } + else { + this.log(`Swanky node version: ${this.swankyConfig.node.version}`); + } + } +} diff --git a/src/lib/cargoContractInfo.ts b/src/lib/cargoContractInfo.ts new file mode 100644 index 00000000..eafdd57d --- /dev/null +++ b/src/lib/cargoContractInfo.ts @@ -0,0 +1,13 @@ +export interface CargoContractInkDependency { + minCargoContractVersion: string; + validInkVersionRange: string; +} + +// Keep cargo-contract versions in descending order +// Ranges are supported by semver +export const CARGO_CONTRACT_INK_DEPS: CargoContractInkDependency[] = [ + { minCargoContractVersion: "4.0.0", validInkVersionRange: "<99.0.0" }, // Non-max version known yet: a very high version is used as fallback in the meantime + { minCargoContractVersion: "2.2.0", validInkVersionRange: "<5.0.0" }, + { minCargoContractVersion: "2.0.2", validInkVersionRange: "<4.2.0" }, + { minCargoContractVersion: "2.0.0", validInkVersionRange: "<4.0.1" }, +]; \ No newline at end of file diff --git a/src/lib/consts.ts b/src/lib/consts.ts index d48b2b67..ed9e063b 100644 --- a/src/lib/consts.ts +++ b/src/lib/consts.ts @@ -1,3 +1,5 @@ +import { swankyNodeVersions } from "./nodeInfo.js"; + export const DEFAULT_NETWORK_URL = "ws://127.0.0.1:9944"; export const DEFAULT_ASTAR_NETWORK_URL = "wss://rpc.astar.network"; export const DEFAULT_SHIDEN_NETWORK_URL = "wss://rpc.shiden.astar.network"; @@ -5,3 +7,5 @@ export const DEFAULT_SHIBUYA_NETWORK_URL = "wss://shibuya.public.blastapi.io"; export const ARTIFACTS_PATH = "artifacts"; export const TYPED_CONTRACTS_PATH = "typedContracts"; + +export const DEFAULT_NODE_INFO = swankyNodeVersions.get("1.6.0")!; diff --git a/src/lib/nodeInfo.ts b/src/lib/nodeInfo.ts index 3064488a..59e2f415 100644 --- a/src/lib/nodeInfo.ts +++ b/src/lib/nodeInfo.ts @@ -1,17 +1,123 @@ -export type nodeInfo = typeof swankyNode; - -export const swankyNode = { - version: "1.6.0", - polkadotPalletVersions: "polkadot-v0.9.39", - supportedInk: "v4.2.0", +export interface nodeInfo { + version: string; + polkadotPalletVersions: string; + supportedInk: string; downloadUrl: { darwin: { - "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", - "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz" - }, + "arm64"?: string; + "x64"?: string; + }; linux: { - "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-aarch64.tar.gz", - "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-x86_64.tar.gz", + "arm64"?: string; + "x64"?: string; + }; + }; +} + +export const swankyNodeVersions = new Map([ + ["1.6.0", { + version: "1.6.0", + polkadotPalletVersions: "polkadot-v0.9.39", + supportedInk: "v4.3.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.6.0/swanky-node-v1.6.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.5.0", { + version: "1.5.0", + polkadotPalletVersions: "polkadot-v0.9.39", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.5.0/swanky-node-v1.5.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.4.0", { + version: "1.4.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.4.0/swanky-node-v1.4.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.3.0", { + version: "1.3.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.3.0/swanky-node-v1.3.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.2.0", { + version: "1.2.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-macOS-universal.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-macOS-universal.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-ubuntu-aarch64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.2.0/swanky-node-v1.2.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.1.0", { + version: "1.1.0", + polkadotPalletVersions: "polkadot-v0.9.37", + supportedInk: "v4.0.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-macOS-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-macOS-x86_64.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-ubuntu-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.1.0/swanky-node-v1.1.0-ubuntu-x86_64.tar.gz", + } + } + }], + ["1.0.0", { + version: "1.0.0", + polkadotPalletVersions: "polkadot-v0.9.30", + supportedInk: "v3.4.0", + downloadUrl: { + darwin: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-macOS-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-macOS-x86_64.tar.gz" + }, + linux: { + "arm64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-ubuntu-x86_64.tar.gz", + "x64": "https://github.com/AstarNetwork/swanky-node/releases/download/v1.0.0/swanky-node-v1.0.0-ubuntu-x86_64.tar.gz", + } } - }, -}; + }] +]); diff --git a/src/lib/prompts.ts b/src/lib/prompts.ts index 259c45a9..3ee17625 100644 --- a/src/lib/prompts.ts +++ b/src/lib/prompts.ts @@ -11,6 +11,16 @@ export function pickTemplate(templateList: string[]): ListQuestion { }; } +export function pickNodeVersion(nodeVersions: string[]): ListQuestion { + if (!nodeVersions?.length) throw new ConfigError("Node version list is empty!"); + return { + name: "version", + type: "list", + choices: nodeVersions, + message: "Which node version should we use?", + }; +} + export function name( subject: string, initial?: (answers: Answers) => string, diff --git a/src/types/index.ts b/src/types/index.ts index aa13a0df..7ff5b9f6 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -11,7 +11,7 @@ export interface ChainProperty { export type ExtrinsicPayload = SubmittableExtrinsic<"promise">; -export interface Encrypted { iv: string; data: string }; +export interface Encrypted { iv: string; data: string } export interface AccountData { isDev: boolean; @@ -43,6 +43,7 @@ export interface SwankyConfig { polkadotPalletVersions: string; localPath: string; supportedInk: string; + version: string; }; accounts: AccountData[]; contracts: Record | Record;