UNPKG

@acurast/cli

Version:

A cli to interact with the Acurast Cloud.

206 lines 9.68 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { Option } from 'commander'; import { acurastColor } from '../util.js'; import * as ora from '../util/ora.js'; import { sendCode } from '../live-code.js'; import { readFileSync, statSync } from 'fs'; import { addLiveCodeProcessor, readLiveCodeProcessors, } from '../services/storage.js'; import { loadConfig } from '../acurast/loadConfig.js'; import { parse } from '../util/parse-duration.js'; import { input } from '@inquirer/prompts'; import { createJob } from '../acurast/createJob.js'; import { DeploymentStatus } from '../acurast/types.js'; import { AssignmentStrategyVariant, } from '../types.js'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { shortenString } from '../util/shortenString.js'; import { red, green, yellowBright } from 'ansis'; import { RPC } from '../config.js'; import { jobToNumber } from '../util/jobToNumber.js'; import { convertConfigToJob } from '../acurast/convertConfigToJob.js'; export const addCommandLive = (program) => { program .command('live [project]') .description('Run the code in a live code environment on a remote processor') .addOption(new Option('-s, --setup', 'Set up a live code environment for the project.')) .action((project, options) => __awaiter(void 0, void 0, void 0, function* () { var _a; if (options.setup) { const unparsedDuration = yield input({ message: 'Enter the duration (eg. 1h, 2d):', validate: (input) => { var _a; const parsed = ((_a = parse(input)) !== null && _a !== void 0 ? _a : 0).toString(); const value = Number(parsed); if (isNaN(value) || value <= 0) { return 'Please enter a valid number greater than 0'; } return true; }, }); const parsedDuration = ((_a = parse(unparsedDuration)) !== null && _a !== void 0 ? _a : 0).toString(); const durationInMilliseconds = Number(parsedDuration); const numberOfProcessors = Number(yield input({ message: 'On how many processors?:', validate: (input) => { const value = Number(input); if (isNaN(value) || value <= 0) { return 'Please enter a valid number greater than 0'; } if (isNaN(value) || value > 10) { return 'Please enter a number lower than 10'; } return true; }, })); const spinner = ora.default('Setting up live code environment'); spinner.start(); const jobId = yield new Promise((resolve) => { const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const filePath = join(__dirname, '..', 'util', 'live-code-processor.js'); const config = { projectName: 'report', fileUrl: filePath, network: 'canary', onlyAttestedDevices: false, startAt: { msFromNow: 300000, }, assignmentStrategy: { type: AssignmentStrategyVariant.Single, }, execution: { type: 'onetime', maxExecutionTimeInMs: durationInMilliseconds, }, maxAllowedStartDelayInMs: 60000, usageLimit: { maxMemory: 0, maxNetworkRequests: 0, maxStorage: 0, }, numberOfReplicas: numberOfProcessors, requiredModules: [], minProcessorReputation: 0, maxCostPerExecution: 10000000000, includeEnvironmentVariables: [], processorWhitelist: [], }; const job = convertConfigToJob(config); createJob(config, job, RPC, [], false, (status, data) => { if (status === DeploymentStatus.WaitingForMatch) { const jobId = data.jobIds[0]; resolve(jobId); spinner.succeed('Live code environment scheduled'); } }); }); console.log('Please go to the follow link and copy the "Deployment Public Key" of the assigned processor, (it may take a few minutes until it\'s available)'); console.log(''); console.log(`https://hub.acurast.com/job-detail/acurast-${jobId[0].acurast}-${jobToNumber(jobId)}`); console.log(''); const processorPublicKey = yield input({ message: 'Deployment Public Key', validate: (input) => { if (!input) { return 'Please enter a valid public key'; } if (!input.startsWith('0x')) { return 'Please enter a valid public key'; } return true; }, }); addLiveCodeProcessor({ publicKey: processorPublicKey, }); if (numberOfProcessors > 1) { console.log('To add more processors to the list, open ".acurast/live-code-processors.json" and add them manually.'); } console.log('Live code environment set up! Run `acurast live` to run your code on that processor.'); return process.exit(0); } let config; try { config = loadConfig(project); } catch (e) { console.log(e.message); return; } // console.log(config); if (!config) { throw new Error('No project found'); } // Get the file size in bytes const stats = statSync(config.fileUrl); // Check if file size is greater than 500KB const fileSizeInBytes = stats.size; const fileSizeInKB = fileSizeInBytes / 1024; if (fileSizeInKB > 500) { console.log('File is larger than 500kb. This is too big for the live-code environment.'); return; } const code = readFileSync(config.fileUrl, 'utf-8'); // TODO: Handle expired const liveCodeProcessors = readLiveCodeProcessors(); if (liveCodeProcessors.length === 0) { throw new Error('No processor found. Run `acurast live --setup`'); } const spinner = ora.default(`Running code on ${liveCodeProcessors.length} processor${liveCodeProcessors.length > 1 ? 's' : ''}`); spinner.start(); let terminations = 0; const registerTermination = () => { terminations++; if (terminations >= liveCodeProcessors.length) { spinner.stop(); process.exit(0); } }; liveCodeProcessors.forEach((processor) => { const timeout = setTimeout(() => { spinner.stop(); console.log(`${shortenString(processor.publicKey)} ${red('Error, no response from processor')}`); registerTermination(); spinner.start(); }, 5000); sendCode(processor.publicKey, code, (event) => { if (timeout) { clearTimeout(timeout); } spinner.stop(); // Sometimes messages arrive out of order, so we wait a little bit before exiting if (event.type === 'start') { console.log(`${shortenString(processor.publicKey)} ${yellowBright('Acknowledged, running code...')}`); } if (event.type === 'log') { if (Array.isArray(event.data)) { console.log(shortenString(processor.publicKey), acurastColor(`Log:`), ...event.data); } else { console.log(shortenString(processor.publicKey), acurastColor(`Log:`), event.data); } } if (event.type === 'success') { console.log(`${shortenString(processor.publicKey)} ${green('Success')}`); registerTermination(); } if (event.type === 'error') { console.log(`${shortenString(processor.publicKey)} ${red('Error')}: ${event.data}`); registerTermination(); } spinner.start(); }); }); })); }; //# sourceMappingURL=live.js.map