{"version":3,"sources":["index.ts","proxy.ts","docker.ts"],"sourcesContent":["import { Option, Plugin, PositionalArg, Task } from '@taqueria/node-sdk';\nimport proxy from './proxy';\n\nPlugin.create(_i18n => ({\n\talias: 'tezbox',\n\tschema: '1.0',\n\tversion: '0.1',\n\ttasks: [\n\t\tTask.create({\n\t\t\ttask: 'start sandbox',\n\t\t\tcommand: 'start sandbox',\n\t\t\taliases: ['start tezbox'],\n\t\t\tdescription: 'Starts a TezBox sandbox',\n\t\t\toptions: [],\n\t\t\thandler: 'proxy',\n\t\t\tencoding: 'none',\n\t\t}),\n\t\tTask.create({\n\t\t\ttask: 'stop sandbox',\n\t\t\tcommand: 'stop sandbox',\n\t\t\taliases: ['stop tezbox'],\n\t\t\tdescription: 'Stops a TezBox sandbox',\n\t\t\toptions: [],\n\t\t\thandler: 'proxy',\n\t\t}),\n\t\tTask.create({\n\t\t\ttask: 'restart sandbox',\n\t\t\tcommand: 'restart sandbox',\n\t\t\taliases: ['restart tezbox'],\n\t\t\tdescription: 'Restarts a TezBox sandbox',\n\t\t\toptions: [],\n\t\t\thandler: 'proxy',\n\t\t}),\n\t\tTask.create({\n\t\t\ttask: 'list accounts',\n\t\t\tcommand: 'list accounts',\n\t\t\taliases: [],\n\t\t\tdescription: 'List the balances of all sandbox accounts',\n\t\t\toptions: [],\n\t\t\thandler: 'proxy',\n\t\t\tencoding: 'json',\n\t\t}),\n\t\tTask.create({\n\t\t\ttask: 'bake',\n\t\t\tcommand: 'bake',\n\t\t\taliases: ['b'],\n\t\t\tdescription: 'Manually bake a block. Use when the \"baking\" setting of a TezBox sandbox is set to \"disabled\".',\n\t\t\toptions: [\n\t\t\t\tOption.create({\n\t\t\t\t\tflag: 'watch',\n\t\t\t\t\tshortFlag: 'w',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Watch for operations as they are injected into the mempool and bake them as immediate as possible.',\n\t\t\t\t\tboolean: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t\thandler: 'proxy',\n\t\t\tencoding: 'none',\n\t\t}),\n\t\tTask.create({\n\t\t\ttask: 'show protocols',\n\t\t\tcommand: 'show protocols',\n\t\t\taliases: ['list protocols'],\n\t\t\tdescription: 'List protocols understood by this version of TezBox',\n\t\t\toptions: [],\n\t\t\thandler: 'proxy',\n\t\t\tencoding: 'json',\n\t\t}),\n\t],\n\tproxy: proxy,\n}), process.argv);\n","import {\n\texecCmd,\n\tgetArch,\n\tgetDockerImage,\n\tSandboxAccountConfig,\n\tSandboxConfig,\n\tsendAsyncErr,\n\tsendAsyncJsonRes,\n\tsendAsyncRes,\n} from '@taqueria/node-sdk';\nimport { generateSecretKey, InMemorySigner } from '@taquito/signer';\nimport BigNumber from 'bignumber.js';\nimport * as bip39 from 'bip39';\nimport { createHash } from 'crypto';\nimport { create } from 'domain';\nimport * as fs from 'fs';\nimport * as hjson from 'hjson';\nimport * as path from 'path';\nimport { getDefaultDockerImage } from './docker';\nimport { Opts } from './types';\n\ntype ConfigV1Environment = {\n\tsandboxes?: string[];\n};\n\ntype Mutez = string | number; // Represents balance in mutez\n\ntype InstantiatedAccount = Omit<SandboxAccountConfig, 'encryptedKey'> & {\n\tencryptedKey?: string;\n};\n\ninterface TezboxAccount {\n\tpkh: string;\n\tpk: string;\n\tsk: string;\n\tbalance: string;\n}\n\ntype SandboxConfigV1 = SandboxConfig;\n\ninterface ProtocolMapping {\n\tid: string; // e.g., \"Proxford\"\n\thash: string; // e.g., \"PsDELPH1...\"\n}\n\ninterface DockerRunParams {\n\tplatform: string;\n\timage: string;\n\tcontainerName: string;\n\tconfigDir: string;\n\tdataDir: string;\n\tport: number;\n}\n\nenum BakingOption {\n\tENABLED = 'enabled',\n\tDISABLED = 'disabled',\n}\n\n/**\n * Logger utility for standardized logging.\n */\nconst logger = {\n\tinfo: (message: string) => console.log(message),\n\twarn: (message: string) => console.warn(message),\n\terror: (message: string) => console.error(message),\n};\n\n/**\n * Extracts error message from unknown error type and prepends a prefix.\n/**\n * Extracts error message from unknown error type and optionally prepends a prefix.\n */\nfunction getErrorMessage(prefix: string, error: unknown): string {\n\tif (prefix === '') {\n\t\treturn error instanceof Error ? error.message : String(error);\n\t}\n\tif (typeof error === 'boolean') {\n\t\treturn `${prefix}:`;\n\t}\n\tconst errorString = error instanceof Error ? error.message : String(error);\n\treturn `${prefix}: ${errorString}`;\n}\n\n/**\n * Creates a command runner with optional logging capability\n */\nfunction createCommandRunner(enableLogging: boolean = false) {\n\tconst logFile = path.join(process.cwd(), 'tezbox-commands.log');\n\n\tasync function logExecution(sections: Record<string, string>): Promise<void> {\n\t\tif (!enableLogging) return;\n\n\t\tconst logEntry = Object.entries(sections)\n\t\t\t.map(([header, content]) =>\n\t\t\t\t[\n\t\t\t\t\t`\\n=== ${header} ===`,\n\t\t\t\t\tcontent || '[no content]',\n\t\t\t\t].join('\\n')\n\t\t\t)\n\t\t\t.join('\\n');\n\n\t\tawait fs.promises.appendFile(logFile, logEntry + '\\n\\n');\n\t}\n\n\t/**\n\t * Executes a shell command and standardizes error handling.\n\t */\n\treturn async function runCommand(\n\t\tcmd: string,\n\t\tstderrHandler?: (stderr: string) => void | Promise<void>,\n\t): Promise<{ stdout: string }> {\n\t\tawait logExecution({ COMMAND: cmd });\n\n\t\ttry {\n\t\t\tconst { stdout, stderr } = await execCmd(cmd);\n\n\t\t\tawait logExecution({\n\t\t\t\tSTDOUT: stdout,\n\t\t\t\tSTDERR: stderr.trim(),\n\t\t\t});\n\n\t\t\tif (stderr.trim()) {\n\t\t\t\tif (stderrHandler) {\n\t\t\t\t\tawait stderrHandler(stderr.trim());\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(stderr.trim());\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { stdout };\n\t\t} catch (error) {\n\t\t\tawait logExecution({\n\t\t\t\tERROR: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\n\t\t\tthrow new Error(getErrorMessage(`Command failed`, error));\n\t\t}\n\t};\n}\n\n// Create the runCommand function with logging enabled or disabled\n// const runCommand = createCommandRunner(true); // Set to false to disable logging\n\n/**\n * Executes a shell command and standardizes error handling.\n */\nasync function runCommand(\n\tcmd: string,\n\tstderrHandler?: (stderr: string) => void | Promise<void>,\n): Promise<{ stdout: string }> {\n\ttry {\n\t\tconst { stdout, stderr } = await execCmd(cmd);\n\t\tif (stderr.trim()) {\n\t\t\tif (stderrHandler) {\n\t\t\t\tawait stderrHandler(stderr.trim());\n\t\t\t} else {\n\t\t\t\tthrow new Error(stderr.trim());\n\t\t\t}\n\t\t}\n\t\treturn { stdout };\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage(`Command failed`, error));\n\t}\n}\n\n/**\n * Checks if the given environment is configured for TezBox.\n */\nfunction isTezBoxEnvironment(taskArgs: Opts): boolean {\n\tconst environment = taskArgs.config.environment[taskArgs.env];\n\tif (!environment || typeof environment !== 'object') return false;\n\n\tconst sandboxes = (environment as ConfigV1Environment).sandboxes;\n\tif (!Array.isArray(sandboxes) || sandboxes.length === 0) return false;\n\n\t// Currently, we don't have a way to tell if a sandbox is TezBox-provided\n\treturn true;\n}\n\n/**\n * Creates a Tezos account with the specified name and balance.\n */\nasync function instantiateDeclaredAccount(\n\tdeclaredAccountName: string,\n\tbalanceInMutez: BigNumber,\n): Promise<InstantiatedAccount> {\n\t// Generate a new account using BIP39 and Tezos key derivation\n\tconst account = await createNewAccount();\n\n\t// Return the instantiated account with real credentials\n\treturn {\n\t\tencryptedKey: `unencrypted:${account.pk}`,\n\t\tpublicKeyHash: account.pkh,\n\t\tsecretKey: account.sk,\n\t};\n}\n\n/**\n * Throws warning indicating function is not implemented yet.\n */\nasync function getInstantiatedAccounts(taskArgs: Opts): Promise<Record<string, InstantiatedAccount>> {\n\tconst sandboxConfig = getSandboxConfig(taskArgs);\n\tif (!sandboxConfig.accounts) {\n\t\tthrow new Error('No instantiated accounts found in sandbox config.');\n\t}\n\tconst accounts = sandboxConfig.accounts as Record<string, InstantiatedAccount>;\n\treturn Object.entries(accounts)\n\t\t.filter(([key]) => key !== 'default')\n\t\t.reduce((acc, [key, value]) => {\n\t\t\tacc[key] = value;\n\t\t\treturn acc;\n\t\t}, {} as Record<string, InstantiatedAccount>);\n}\n\n/**\n * Gets the sandbox configuration for the given environment.\n */\nfunction getSandboxConfig(taskArgs: Opts): SandboxConfigV1 {\n\tif (!isTezBoxEnvironment(taskArgs)) {\n\t\tthrow new Error(\n\t\t\t`This configuration doesn't appear to be configured to use TezBox environments. Check the ${taskArgs.env} environment in your .taq/config.json.`,\n\t\t);\n\t}\n\n\tconst environment = taskArgs.config.environment[taskArgs.env] as ConfigV1Environment;\n\tconst sandboxName = environment.sandboxes?.[0];\n\tif (sandboxName) {\n\t\tconst sandboxConfig = taskArgs.config.sandbox?.[sandboxName];\n\t\tif (sandboxConfig) {\n\t\t\tconst retval: SandboxConfigV1 = {\n\t\t\t\tblockTime: 1,\n\t\t\t\tbaking: BakingOption.ENABLED,\n\t\t\t\t...sandboxConfig,\n\t\t\t\t...sandboxConfig.annotations,\n\t\t\t};\n\n\t\t\treturn retval;\n\t\t}\n\t}\n\tthrow new Error(`No sandbox configuration found for ${taskArgs.env} environment.`);\n}\n\n/**\n * Gets or creates instantiated accounts.\n */\nasync function getOrCreateInstantiatedAccounts(\n\ttaskArgs: Opts,\n): Promise<Record<string, InstantiatedAccount>> {\n\tlet instantiatedAccounts: Record<string, InstantiatedAccount>;\n\n\ttry {\n\t\t// Attempt to get instantiated accounts\n\t\tinstantiatedAccounts = await getInstantiatedAccounts(taskArgs);\n\t} catch (error) {\n\t\t// No instantiated accounts available, so we need to instantiate them\n\t\tinstantiatedAccounts = {};\n\t\tconst declaredAccounts = taskArgs.config.accounts as Record<string, Mutez>;\n\n\t\tfor (const [accountName, balanceInMutez] of Object.entries(declaredAccounts)) {\n\t\t\t// Convert balance to BigNumber, removing any underscores used for formatting\n\t\t\tconst balanceInMutezBN = new BigNumber(balanceInMutez.toString().replace(/_/g, ''));\n\n\t\t\t// Instantiate the declared account\n\t\t\tconst instantiatedAccount = await instantiateDeclaredAccount(accountName, balanceInMutezBN);\n\n\t\t\t// Store the instantiated account\n\t\t\tinstantiatedAccounts[accountName] = instantiatedAccount;\n\t\t}\n\n\t\t// Optionally, save the instantiated accounts to persist them for future runs\n\t\tawait saveInstantiatedAccounts(instantiatedAccounts, taskArgs.projectDir, taskArgs.env);\n\t}\n\n\treturn instantiatedAccounts;\n}\n\n/**\n * Saves instantiated accounts to the local configuration file.\n * @param accounts Record of instantiated accounts\n * @param projectDir Project directory path\n * @param env Environment name\n */\nasync function saveInstantiatedAccounts(\n\taccounts: Record<string, InstantiatedAccount>,\n\tprojectDir: string,\n\tenv: string,\n): Promise<void> {\n\tconst configPath = path.join(projectDir, `.taq/config.local.${env}.json`);\n\n\ttry {\n\t\t// Read existing config or use an empty object if file doesn't exist\n\t\tlet config: Record<string, any> = {};\n\t\ttry {\n\t\t\tconst configContent = await fs.promises.readFile(configPath, 'utf8');\n\t\t\tconfig = JSON.parse(configContent);\n\t\t} catch (error) {\n\t\t\t// If file doesn't exist or there's an error reading it, we'll use an empty object\n\t\t}\n\n\t\t// Convert InstantiatedAccount to SandboxAccountConfig, omitting encryptedKey\n\t\tconst sandboxAccounts: Record<string, Omit<SandboxAccountConfig, 'encryptedKey'>> = {};\n\t\tfor (const [name, account] of Object.entries(accounts)) {\n\t\t\tsandboxAccounts[name] = {\n\t\t\t\tpublicKeyHash: account.publicKeyHash,\n\t\t\t\tsecretKey: account.secretKey,\n\t\t\t};\n\t\t}\n\n\t\t// Update only the accounts property in the config\n\t\tconfig.accounts = sandboxAccounts;\n\n\t\t// Ensure the directory exists\n\t\tawait fs.promises.mkdir(path.dirname(configPath), { recursive: true });\n\n\t\t// Write the updated config back to the file\n\t\tawait fs.promises.writeFile(configPath, JSON.stringify(config, null, 2), 'utf8');\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage('Failed to save instantiated accounts', error));\n\t}\n}\n\n/**\n * Generates a mnemonic phrase using BIP39.\n * @param strength The entropy bit length, defaults to 128 (resulting in a 12-word mnemonic).\n * @returns A promise that resolves to the generated mnemonic phrase.\n */\nasync function generateMnemonic(strength: number = 128): Promise<string> {\n\ttry {\n\t\tconst mnemonic = bip39.generateMnemonic(strength);\n\t\treturn mnemonic;\n\t} catch (error) {\n\t\tconsole.error('Error generating mnemonic:', error);\n\t\tthrow new Error('Failed to generate mnemonic');\n\t}\n}\n\n// Function to generate a new implicit account\nasync function createNewAccount() {\n\tconst mnemonic = await generateMnemonic();\n\n\t// Generate the BIP39 seed from the mnemonic\n\tconst seed = await bip39.mnemonicToSeed(mnemonic);\n\n\t// Convert the seed (Buffer) to a UInt8Array\n\tconst seedUInt8Array = new Uint8Array(seed);\n\n\t// Generate the secret key\n\tconst secretKey = generateSecretKey(seedUInt8Array, \"m/44'/1729'/0'/0'\", 'ed25519');\n\n\t// Derive the public key and public key hash from the secret key\n\tconst signer = new InMemorySigner(secretKey);\n\tconst publicKey = await signer.publicKey();\n\tconst publicKeyHash = await signer.publicKeyHash();\n\n\t// Return the object with pk, pkh, sk, and balance\n\treturn {\n\t\tpk: publicKey,\n\t\tpkh: publicKeyHash,\n\t\tsk: `unencrypted:${secretKey}`,\n\t};\n}\n\nfunction createFunderAccount() {\n\treturn createNewAccount().then(account => ({\n\t\tpublicKeyHash: account.pkh,\n\t\tsecretKey: account.sk,\n\t}));\n}\n\nasync function getPublicKeyFromSecretKey(secretKey: string) {\n\t// Initialize the signer with the secret key\n\tconst signer = await InMemorySigner.fromSecretKey(secretKey.replace('unencrypted:', ''));\n\n\t// Get the public key\n\tconst publicKey = await signer.publicKey();\n\n\treturn publicKey;\n}\n\n/**\n * Prepares TezBox accounts configuration.\n */\n/**\n * Prepares TezBox accounts configuration.\n */\nasync function prepareTezBoxAccounts(\n\tinstantiatedAccounts: Record<string, InstantiatedAccount>,\n\tdeclaredAccounts: Record<string, Mutez>,\n): Promise<Record<string, TezboxAccount>> {\n\t// Add funder account to instantiatedAccounts\n\t// instantiatedAccounts['funder'] = await createFunderAccount();\n\n\tconst tezboxAccounts: Record<string, TezboxAccount> = {};\n\n\tfor (const [accountName, accountData] of Object.entries(instantiatedAccounts)) {\n\t\tif (accountName === 'default') continue;\n\n\t\tconst secretKey = accountData.secretKey;\n\t\ttezboxAccounts[accountName] = {\n\t\t\tpkh: accountData.publicKeyHash,\n\t\t\tpk: await getPublicKeyFromSecretKey(secretKey),\n\t\t\tsk: secretKey,\n\t\t\tbalance: accountName === 'funder'\n\t\t\t\t? new BigNumber(100000000000000).toString()\n\t\t\t\t: new BigNumber(declaredAccounts[accountName].toString()).toString(),\n\t\t};\n\t}\n\n\treturn tezboxAccounts;\n}\n\n/**\n * Writes accounts.hjson file.\n */\nasync function writeAccountsHjson(\n\ttezboxAccounts: Record<string, TezboxAccount>,\n\ttezBoxConfigDir: string,\n): Promise<void> {\n\t// TODO: Remove for debugging\n\tawait Promise.resolve();\n\n\t// // Rearrange accounts record so that funder is first\n\t// const funderAccount = tezboxAccounts['funder'];\n\t// delete tezboxAccounts['funder'];\n\t// tezboxAccounts = { funder: funderAccount, ...tezboxAccounts };\n\n\t// Convert the accounts object to HJSON format\n\tconst hjsonContent = hjson.stringify(tezboxAccounts, {\n\t\tquotes: 'min',\n\t\tbracesSameLine: true,\n\t\tseparator: false,\n\t});\n\n\t// Remove quotes around sk values and ensure proper indentation\n\tconst fixedHjsonContent = hjsonContent.replaceAll('\"', '');\n\n\t// Write the accounts.hjson file\n\tconst accountsHjsonPath = path.join(tezBoxConfigDir, 'accounts.hjson');\n\tawait fs.promises.writeFile(accountsHjsonPath, fixedHjsonContent, 'utf8');\n}\n\n/**\n * Gets the declared accounts from the task arguments and removes underscores from Mutez values.\n */\nfunction getDeclaredAccounts(taskArgs: Opts): Record<string, Mutez> {\n\tconst declaredAccounts = taskArgs.config.accounts as Record<string, Mutez>;\n\treturn Object.entries(declaredAccounts).reduce((acc, [key, value]) => {\n\t\tacc[key] = value.toString().replace(/_/g, '');\n\t\treturn acc;\n\t}, {} as Record<string, Mutez>);\n}\n\n/**\n * Prepares accounts.hjson for TezBox.\n */\nasync function prepareAccountsHjson(taskArgs: Opts, tezBoxConfigDir: string): Promise<void> {\n\ttry {\n\t\t// Get or create instantiated accounts\n\t\tconst instantiatedAccounts = await getOrCreateInstantiatedAccounts(taskArgs);\n\n\t\t// Retrieve declared accounts\n\t\tconst declaredAccounts = getDeclaredAccounts(taskArgs);\n\n\t\t// Prepare tezbox accounts\n\t\tconst tezboxAccounts = await prepareTezBoxAccounts(instantiatedAccounts, declaredAccounts);\n\n\t\t// Write the accounts.hjson file\n\t\tawait writeAccountsHjson(tezboxAccounts, tezBoxConfigDir);\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage(`Failed to prepare accounts`, error));\n\t}\n}\n\n/**\n * Prepares bakers.hjson for TezBox.\n */\nasync function prepareBakersHjson(taskArgs: Opts, tezBoxConfigDir: string): Promise<void> {\n\ttry {\n\t\t// Get declared accounts\n\t\tconst declaredAccounts = getDeclaredAccounts(taskArgs);\n\n\t\t// Calculate total balance\n\t\tconst totalBalance = Object.values(declaredAccounts).reduce(\n\t\t\t(sum, balance) => BigNumber.sum(sum, balance),\n\t\t\tnew BigNumber(0),\n\t\t).toString();\n\n\t\t// Prepare bakers object\n\t\tconst bakers = {\n\t\t\tbaker1: {\n\t\t\t\tpkh: 'tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU',\n\t\t\t\tpk: 'edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV',\n\t\t\t\tsk: 'unencrypted:edsk4ArLQgBTLWG5FJmnGnT689VKoqhXwmDPBuGx3z4cvwU9MmrPZZ',\n\t\t\t\tbalance: totalBalance,\n\t\t\t},\n\t\t\tbaker2: {\n\t\t\t\tpkh: 'tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN',\n\t\t\t\tpk: 'edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9',\n\t\t\t\tsk: 'unencrypted:edsk39qAm1fiMjgmPkw1EgQYkMzkJezLNewd7PLNHTkr6w9XA2zdfo',\n\t\t\t\tbalance: totalBalance,\n\t\t\t},\n\t\t\tbaker3: {\n\t\t\t\tpkh: 'tz1b7tUupMgCNw2cCLpKTkSD1NZzB5TkP2sv',\n\t\t\t\tpk: 'edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU',\n\t\t\t\tsk: 'unencrypted:edsk2uqQB9AY4FvioK2YMdfmyMrer5R8mGFyuaLLFfSRo8EoyNdht3',\n\t\t\t\tbalance: totalBalance,\n\t\t\t},\n\t\t};\n\n\t\t// Convert the bakers object to HJSON format\n\t\tconst hjsonContent = hjson.stringify(bakers, {\n\t\t\tquotes: 'min',\n\t\t\tbracesSameLine: true,\n\t\t\tseparator: false,\n\t\t});\n\n\t\t// Remove quotes around sk values and ensure proper indentation\n\t\tconst fixedHjsonContent = hjsonContent.replaceAll('\"', '');\n\n\t\t// Write the bakers.hjson file\n\t\tconst bakersHjsonPath = path.join(tezBoxConfigDir, 'bakers.hjson');\n\t\tawait fs.promises.writeFile(bakersHjsonPath, fixedHjsonContent, 'utf8');\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage(`Failed to prepare bakers`, error));\n\t}\n}\n\n/**\n * Generates a project ID based on the project directory.\n */\nfunction getProjectId(taskArgs: Opts): string {\n\treturn createHash('sha256').update(taskArgs.projectDir).digest('hex');\n}\n\n/**\n * Gets the docker container name for the sandbox.\n */\nfunction getDockerContainerName(taskArgs: Opts): string {\n\tconst projectId = getProjectId(taskArgs);\n\treturn `taq-${taskArgs.env}-${projectId}`;\n}\n\n/**\n * Gets the TezBox configuration directory.\n */\nfunction getTezBoxConfigDir(taskArgs: Opts): string {\n\tconst containerName = getDockerContainerName(taskArgs);\n\treturn path.join(taskArgs.projectDir, `.taq/.${containerName}/config`);\n}\n\n/**\n * Gets the TezBox data directory.\n */\nfunction getTezBoxDataDir(taskArgs: Opts): string {\n\tconst containerName = getDockerContainerName(taskArgs);\n\treturn path.join(taskArgs.projectDir, `.taq/.${containerName}/data`);\n}\n\n/**\n * Gets the docker image for TezBox.\n */\nfunction getImage(taskArgs: Opts): string {\n\treturn getDockerImage(getDefaultDockerImage(taskArgs), 'TAQ_TEZBOX_IMAGE');\n}\n\n/**\n * Checks if the sandbox is running.\n */\nasync function isSandboxRunning(taskArgs: Opts): Promise<boolean> {\n\tconst containerName = getDockerContainerName(taskArgs);\n\tconst cmd = `docker ps --filter \"name=${containerName}\" --format \"{{.ID}}\"`;\n\tconst { stdout } = await runCommand(cmd);\n\treturn stdout.trim() !== '';\n}\n\n/**\n * Checks if the sandbox is already running.\n */\nasync function checkSandboxRunning(taskArgs: Opts): Promise<boolean> {\n\tconst running = await isSandboxRunning(taskArgs);\n\tif (running) {\n\t\tawait sendAsyncRes('Sandbox is already running.');\n\t}\n\treturn running;\n}\n\nfunction getPortNumber(taskArgs: Opts) {\n\tconst rpcUrl = getSandboxConfig(taskArgs).rpcUrl;\n\tconst match = rpcUrl.match(/:(\\d+)/);\n\treturn match ? parseInt(match[1], 10) : 80;\n}\n\nfunction getContainerPort(taskArgs: Opts) {\n\treturn getPortNumber(taskArgs) + 1;\n}\n\n/**\n * Gets the docker run parameters.\n */\nasync function getDockerRunParams(taskArgs: Opts): Promise<DockerRunParams> {\n\tconst image = getImage(taskArgs);\n\tconst containerName = getDockerContainerName(taskArgs);\n\tconst platform = await getArch();\n\tconst configDir = getTezBoxConfigDir(taskArgs);\n\tconst dataDir = getTezBoxDataDir(taskArgs);\n\tconst port = getContainerPort(taskArgs);\n\n\treturn { platform, image, containerName, configDir, dataDir, port };\n}\n\n/**\n * Ensures directories exist.\n */\nasync function ensureDirectoriesExist(directories: string[]): Promise<void> {\n\tawait Promise.all(\n\t\tdirectories.map(dir => fs.promises.mkdir(dir, { recursive: true })),\n\t);\n}\n\n/**\n * Constructs the docker run command.\n */\nfunction constructDockerRunCommand(params: DockerRunParams): string {\n\tconst { platform, image, containerName, configDir, port } = params;\n\n\tconst dockerOptions = [\n\t\t'docker run',\n\t\t'-d',\n\t\t`--platform ${platform}`,\n\t\t'-p 8732:8732',\n\t\t`-p ${port}:20000`,\n\t\t`--name ${containerName}`,\n\t\t`-v \"${configDir}:/tezbox/overrides\"`,\n\t\timage,\n\t\t'S',\n\t];\n\n\treturn dockerOptions.join(' ');\n}\n\n/**\n * Validates the block time in the sandbox configuration.\n */\nfunction validateBlockTime(taskArgs: Opts): number | null {\n\tconst sandboxConfig = getSandboxConfig(taskArgs);\n\tconst blockTime = sandboxConfig.blockTime;\n\tif (blockTime === undefined || blockTime === null) {\n\t\tlogger.warn('Block time is not specified; skipping block_time override.');\n\t\treturn null;\n\t}\n\treturn blockTime;\n}\n\n/**\n * Writes sandbox parameters for a single protocol.\n */\nasync function writeSandboxParameters(\n\tprotocolId: string,\n\tparameters: Record<string, string | number>,\n\ttezBoxConfigDir: string,\n): Promise<void> {\n\tconst protocolsDir = path.join(tezBoxConfigDir, 'protocols', protocolId);\n\tawait fs.promises.mkdir(protocolsDir, { recursive: true });\n\n\tconst hjsonContent = hjson.stringify(parameters, {\n\t\tquotes: 'min',\n\t\tbracesSameLine: true,\n\t\tseparator: false,\n\t});\n\n\tconst sandboxParamsPath = path.join(protocolsDir, 'sandbox-parameters.hjson');\n\tawait fs.promises.writeFile(sandboxParamsPath, hjsonContent, 'utf8');\n\n\t// Ensure the file has write permissions\n\ttry {\n\t\tawait fs.promises.chmod(sandboxParamsPath, 0o644);\n\t} catch (error) {\n\t\tlogger.warn(getErrorMessage(`Failed to set file permissions for ${sandboxParamsPath}`, error));\n\t}\n}\n\n/**\n * Applies block time override to a single protocol.\n */\nasync function applyBlockTimeOverrideToProtocol(\n\tprotocolId: string,\n\tblockTime: number,\n\ttezBoxConfigDir: string,\n): Promise<void> {\n\tconst nonce_revelation_threshold = 16;\n\tconst minimal_block_delay = blockTime;\n\n\tconst parameters = {\n\t\tminimal_block_delay: minimal_block_delay.toString(),\n\t};\n\tawait writeSandboxParameters(protocolId, parameters, tezBoxConfigDir);\n}\n\n/**\n * Applies block time override to multiple protocols.\n */\nasync function applyBlockTimeOverrideToProtocols(\n\tprotocolIds: string[],\n\tblockTime: number,\n\ttezBoxConfigDir: string,\n): Promise<void> {\n\tawait Promise.all(\n\t\tprotocolIds.map(async protocolId => {\n\t\t\t// Skip alpha protocol as it's a placeholder\n\t\t\tif (/^alpha$/i.test(protocolId)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait applyBlockTimeOverrideToProtocol(protocolId, blockTime, tezBoxConfigDir);\n\t\t}),\n\t);\n}\n\n/**\n * Gets protocol identifiers from TezBox configuration.\n */\nasync function getProtocolIds(taskArgs: Opts): Promise<string[]> {\n\tconst image = getImage(taskArgs);\n\n\t// List the protocol directories inside the TezBox image\n\tconst cmd = `docker run --rm --entrypoint ls ${image} /tezbox/configuration/protocols`;\n\tconst { stdout } = await runCommand(cmd);\n\n\tconst protocolIds = stdout\n\t\t.trim()\n\t\t.split('\\n')\n\t\t.map(line => line.trim())\n\t\t.filter(line => line !== '');\n\n\treturn protocolIds;\n}\n\n/**\n * Reads and parses protocol.hjson for a given protocolId.\n */\nasync function readProtocolJson(image: string, protocolId: string): Promise<ProtocolMapping | null> {\n\tconst cmd = `docker run --rm --entrypoint cat ${image} /tezbox/configuration/protocols/${protocolId}/protocol.hjson`;\n\n\ttry {\n\t\tconst { stdout } = await runCommand(cmd);\n\n\t\tif (!stdout.trim()) {\n\t\t\tlogger.warn(`protocol.hjson not found or empty for protocolId ${protocolId}; skipping this protocol.`);\n\t\t\treturn null;\n\t\t}\n\n\t\t// Parse the HJSON content\n\t\tconst protocolData = hjson.parse(stdout);\n\t\tconst protocolHash: string = protocolData.hash;\n\t\tif (protocolHash) {\n\t\t\treturn { id: protocolId, hash: protocolHash };\n\t\t} else {\n\t\t\tlogger.warn(`Protocol hash not found in protocol.hjson for protocolId ${protocolId}; skipping.`);\n\t\t\treturn null;\n\t\t}\n\t} catch (error) {\n\t\tlogger.warn(getErrorMessage(`Failed to read protocol.hjson for protocolId ${protocolId}`, error));\n\t\treturn null;\n\t}\n}\n\n/**\n * Gets protocol mappings.\n */\nasync function getProtocolMappings(taskArgs: Opts): Promise<ProtocolMapping[]> {\n\tconst image = getImage(taskArgs);\n\tconst protocolIds = await getProtocolIds(taskArgs);\n\n\tconst protocolMappingsPromises = protocolIds.map(async protocolId => {\n\t\tconst mapping = await readProtocolJson(image, protocolId);\n\t\treturn mapping;\n\t});\n\n\tconst protocolMappings = await Promise.all(protocolMappingsPromises);\n\treturn protocolMappings.filter((mapping): mapping is ProtocolMapping => mapping !== null);\n}\n\n/**\n * Gets protocol hashes from octez-client.\n */\nasync function getOctezClientProtocols(taskArgs: Opts): Promise<string[]> {\n\tconst image = getImage(taskArgs);\n\tconst cmd = `docker run --rm --entrypoint octez-client ${image} list mockup protocols`;\n\tconst { stdout } = await runCommand(cmd, stderr => {\n\t\tconst ignorableError = [\n\t\t\t'Base directory /tezbox/data/.tezos-client does not exist.',\n\t\t\t'Unable to connect to the node: \"Unix.Unix_error(Unix.ECONNREFUSED, \"connect\", \"\")\"',\n\t\t];\n\n\t\tif (stderr.trim() !== '' && !ignorableError.some(err => stderr.includes(err))) {\n\t\t\tthrow new Error(`Failed to list protocols: ${stderr.trim()}`);\n\t\t}\n\t});\n\n\tconst protocols = stdout\n\t\t.trim()\n\t\t.split('\\n')\n\t\t.filter(line => line.trim() !== '');\n\n\treturn protocols;\n}\n\n/**\n * Prepares sandbox-parameters.hjson for block_time override.\n */\nasync function prepareSandboxParametersHjson(taskArgs: Opts, tezBoxConfigDir: string): Promise<void> {\n\ttry {\n\t\t// Validate block time\n\t\tconst blockTime = validateBlockTime(taskArgs);\n\t\tif (blockTime === null) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the protocol mappings from TezBox\n\t\tconst protocolMappings = await getProtocolMappings(taskArgs);\n\t\tconst hashToIdMap: Record<string, string> = {};\n\t\tfor (const mapping of protocolMappings) {\n\t\t\thashToIdMap[mapping.hash] = mapping.id;\n\t\t}\n\n\t\t// Get the list of protocol hashes supported by octez-client\n\t\tconst protocolHashes = await getOctezClientProtocols(taskArgs);\n\n\t\t// Map protocol hashes to TezBox protocol IDs\n\t\tconst protocolIdsToOverride = protocolHashes\n\t\t\t.map(hash => hashToIdMap[hash])\n\t\t\t.filter((id): id is string => id !== undefined);\n\n\t\tif (protocolIdsToOverride.length === 0) {\n\t\t\tlogger.warn('No matching protocol IDs found; cannot set block_time override.');\n\t\t\treturn;\n\t\t}\n\n\t\t// Debug: Log the protocol IDs to override\n\t\t// logger.info(`Protocol IDs to override: ${protocolIdsToOverride.join(', ')}`);\n\n\t\t// Apply block time override to each protocol ID\n\t\tawait applyBlockTimeOverrideToProtocols(protocolIdsToOverride, blockTime, tezBoxConfigDir);\n\t} catch (error) {\n\t\tconst errorMessage = getErrorMessage(`Failed to prepare sandbox parameters:`, error);\n\t\tthrow new Error(errorMessage);\n\t}\n}\n\n/**\n * Prepares baker.hjson if baking is disabled.\n */\nasync function prepareBakerHjson(tezBoxConfigDir: string): Promise<void> {\n\tconst servicesDir = path.join(tezBoxConfigDir, 'services');\n\ttry {\n\t\tawait fs.promises.mkdir(servicesDir, { recursive: true });\n\n\t\tconst bakerConfig = {\n\t\t\tautostart: false,\n\t\t};\n\n\t\tconst hjsonContent = hjson.stringify(bakerConfig, {\n\t\t\tquotes: 'all',\n\t\t\tbracesSameLine: true,\n\t\t\tseparator: true,\n\t\t});\n\n\t\tconst bakerConfigPath = path.join(servicesDir, 'baker.hjson');\n\t\tawait fs.promises.writeFile(bakerConfigPath, hjsonContent, 'utf8');\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage(`Failed to prepare baker.hjson`, error));\n\t}\n}\n\n/**\n * Prepares TezBox configuration overrides.\n */\nasync function prepareTezBoxOverrides(taskArgs: Opts): Promise<void> {\n\tconst tezBoxConfigDir = getTezBoxConfigDir(taskArgs);\n\n\ttry {\n\t\t// Get sandbox configuration\n\t\tconst sandboxConfig = getSandboxConfig(taskArgs);\n\n\t\t// Ensure the configuration directory exists\n\t\tawait fs.promises.mkdir(tezBoxConfigDir, { recursive: true });\n\n\t\t// Prepare tasks\n\t\tconst tasks: Promise<void>[] = [];\n\n\t\t// Prepare bakers.hjson\n\t\ttasks.push(prepareBakersHjson(taskArgs, tezBoxConfigDir));\n\n\t\t// Prepare accounts.hjson\n\t\tif (taskArgs.config.accounts) {\n\t\t\ttasks.push(prepareAccountsHjson(taskArgs, tezBoxConfigDir));\n\t\t}\n\n\t\t// Prepare sandbox-parameters.hjson for block_time\n\t\tif (sandboxConfig.blockTime) {\n\t\t\ttasks.push(prepareSandboxParametersHjson(taskArgs, tezBoxConfigDir));\n\t\t}\n\n\t\t// Prepare baker.hjson if baking is disabled\n\t\tif (sandboxConfig.baking === BakingOption.DISABLED) {\n\t\t\ttasks.push(prepareBakerHjson(tezBoxConfigDir));\n\t\t}\n\n\t\t// Run all preparations in parallel\n\t\tawait Promise.all(tasks);\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage(`Failed to prepare TezBox overrides`, error));\n\t}\n}\n\nfunction getProxyContainerName(taskArgs: Opts) {\n\treturn `${getDockerContainerName(taskArgs)}-proxy`;\n}\n\nasync function startProxyServer(taskArgs: Opts): Promise<void> {\n\tconst containerPort = getContainerPort(taskArgs);\n\tconst proxyPort = getPortNumber(taskArgs);\n\tconst proxyContainerName = getProxyContainerName(taskArgs);\n\n\tconst proxyCmd = `docker run -d --name ${proxyContainerName} \\\n        --network host \\\n        caddy:2-alpine \\\n        caddy reverse-proxy \\\n        --from http://:${proxyPort} \\\n        --to http://127.0.0.1:${containerPort} \\\n        --access-log`;\n\n\ttry {\n\t\tawait runCommand(proxyCmd);\n\t} catch (error) {\n\t\tthrow new Error(getErrorMessage(`Failed to start Caddy reverse proxy`, error));\n\t}\n}\n\nasync function stopProxyServer(taskArgs: Opts): Promise<void> {\n\tconst proxyContainerName = getProxyContainerName(taskArgs);\n\tconst cmd = `docker rm -f ${proxyContainerName}`;\n\tawait runCommand(cmd);\n}\n\n/**\n * Starts the sandbox.\n */\nasync function startSandbox(taskArgs: Opts): Promise<void> {\n\ttry {\n\t\t// Check for Docker availability\n\t\tawait checkDockerAvailability();\n\n\t\t// Check if the sandbox is already running\n\t\tif (await checkSandboxRunning(taskArgs)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get Docker run parameters\n\t\tconst params = await getDockerRunParams(taskArgs);\n\n\t\t// Ensure necessary directories exist\n\t\tawait ensureDirectoriesExist([params.dataDir, params.configDir]);\n\n\t\t// Prepare TezBox configuration overrides\n\t\tawait prepareTezBoxOverrides(taskArgs);\n\n\t\t// Construct the Docker run command\n\t\tconst cmd = constructDockerRunCommand(params);\n\t\t// logger.info(`Starting sandbox with command: ${cmd}`);\n\n\t\t// Execute the Docker run command\n\t\tawait runCommand(cmd);\n\n\t\t// Start the proxy server\n\t\tawait startProxyServer(taskArgs);\n\n\t\t// Send a success response\n\t\tawait sendAsyncRes('Sandbox started successfully.');\n\t} catch (error) {\n\t\tawait sendAsyncErr(getErrorMessage(`Failed to start sandbox`, error));\n\t}\n}\n\n/**\n * Checks for Docker availability.\n */\nasync function checkDockerAvailability(): Promise<void> {\n\ttry {\n\t\tawait runCommand('docker --version');\n\t} catch (error) {\n\t\tthrow new Error('Docker is not installed or not running. Please install and start Docker.');\n\t}\n}\n\n/**\n * Removes the sandbox container.\n */\nasync function removeSandboxContainer(taskArgs: Opts): Promise<void> {\n\tconst containerName = getDockerContainerName(taskArgs);\n\tconst cmd = `docker rm -f ${containerName}`;\n\n\ttry {\n\t\tawait runCommand(cmd);\n\t} catch (error) {\n\t\tconst errorMessage = getErrorMessage('', error);\n\t\tif (errorMessage.includes('No such container')) {\n\t\t\t// Container does not exist\n\t\t\tawait sendAsyncRes('Sandbox is not running or already stopped.');\n\t\t} else {\n\t\t\tthrow new Error(errorMessage);\n\t\t}\n\t}\n\n\t// Stop the proxy server\n\tawait stopProxyServer(taskArgs);\n}\n\n/**\n * Stops the sandbox.\n */\nasync function stopSandbox(taskArgs: Opts): Promise<void> {\n\ttry {\n\t\t// Attempt to stop and remove the sandbox container\n\t\tawait removeSandboxContainer(taskArgs);\n\n\t\t// Optionally, clean up configuration directory if needed\n\t\tconst configDir = getTezBoxConfigDir(taskArgs);\n\t\tawait fs.promises.rm(configDir, { recursive: true, force: true });\n\n\t\t// Send a success response\n\t\tawait sendAsyncRes('Sandbox stopped and cleaned up.');\n\t} catch (error) {\n\t\tawait sendAsyncErr(getErrorMessage(`Failed to stop sandbox`, error));\n\t}\n}\n\n/**\n * Restarts the sandbox.\n */\nasync function restartSandbox(taskArgs: Opts): Promise<void> {\n\ttry {\n\t\t// Stop the sandbox if it's running\n\t\tawait removeSandboxContainer(taskArgs);\n\n\t\t// Start the sandbox\n\t\tawait startSandbox(taskArgs);\n\n\t\t// Send a success response\n\t\tawait sendAsyncRes('Sandbox restarted successfully.');\n\t} catch (error) {\n\t\tawait sendAsyncErr(getErrorMessage(`Failed to restart sandbox`, error));\n\t}\n}\n\n/**\n * Lists protocols.\n */\nasync function listProtocols(taskArgs: Opts): Promise<void> {\n\ttry {\n\t\tconst protocolHashes = await getOctezClientProtocols(taskArgs);\n\t\tconst protocolObjects = protocolHashes.map(protocol => ({ protocol }));\n\t\tawait sendAsyncJsonRes(protocolObjects);\n\t} catch (error) {\n\t\tawait sendAsyncErr(getErrorMessage(`Failed to list protocols`, error));\n\t}\n}\n\n/**\n * Lists accounts.\n */\nasync function listAccounts(taskArgs: Opts): Promise<void> {\n\ttry {\n\t\tif (await isSandboxRunning(taskArgs)) {\n\t\t\t// List accounts from the sandbox\n\t\t\tconst containerName = getDockerContainerName(taskArgs);\n\t\t\tconst cmd = `docker exec ${containerName} octez-client list known addresses`;\n\t\t\tconst { stdout } = await runCommand(cmd);\n\n\t\t\tif (!stdout.trim()) {\n\t\t\t\tawait sendAsyncRes('No accounts found.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst accounts = stdout\n\t\t\t\t.trim()\n\t\t\t\t.split('\\n')\n\t\t\t\t.filter(line => line.trim() !== '')\n\t\t\t\t.map(line => {\n\t\t\t\t\tconst [name, rest] = line.split(':');\n\t\t\t\t\tconst address = rest ? rest.trim().split(' ')[0] : '';\n\t\t\t\t\treturn { name: name.trim(), address };\n\t\t\t\t});\n\n\t\t\tawait sendAsyncJsonRes(accounts);\n\t\t} else {\n\t\t\tawait sendAsyncErr(`Sandbox is not running. Please start the sandbox before attempting to list accounts.`);\n\t\t}\n\t} catch (error) {\n\t\tawait sendAsyncErr(getErrorMessage(`Failed to list accounts`, error));\n\t}\n}\n\n/**\n * Bakes a block in the sandbox.\n */\nasync function bakeBlock(taskArgs: Opts): Promise<void> {\n\ttry {\n\t\tif (await isSandboxRunning(taskArgs)) {\n\t\t\tconst containerName = getDockerContainerName(taskArgs);\n\t\t\tconst cmd = `docker exec ${containerName} octez-client bake for baker1`;\n\n\t\t\tif (taskArgs.watch) {\n\t\t\t\tconsole.log('Baking on demand as operations are injected.');\n\t\t\t\tconsole.log('Press CTRL-C to stop and exit.');\n\t\t\t\tconsole.log();\n\n\t\t\t\twhile (true) {\n\t\t\t\t\tconsole.log('Waiting for operations to be injected...');\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tconst { stdout } = await runCommand(\n\t\t\t\t\t\t\t`docker exec ${containerName} octez-client rpc get /chains/main/mempool/pending_operations`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst ops = JSON.parse(stdout);\n\t\t\t\t\t\tif (Array.isArray(ops.applied) && ops.applied.length > 0) break;\n\t\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second before checking again\n\t\t\t\t\t}\n\n\t\t\t\t\tawait runCommand(cmd);\n\t\t\t\t\tconsole.log('Block baked.');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait runCommand(cmd);\n\t\t\t\tawait sendAsyncRes('Block baked successfully.');\n\t\t\t}\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tawait sendAsyncErr('Sandbox is not running. Please start the sandbox before attempting to bake a block.');\n\t\t\t} catch {\n\t\t\t\t// Nothing to see here.\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tawait sendAsyncErr(getErrorMessage(`Failed to bake block`, error));\n\t}\n}\n\n/**\n * Main proxy function to handle tasks.\n */\nexport const proxy = async (taskArgs: Opts): Promise<void> => {\n\tif (!isTezBoxEnvironment(taskArgs)) {\n\t\tawait sendAsyncErr(\n\t\t\t`This configuration doesn't appear to be configured to use TezBox environments. Check the ${taskArgs.env} environment in your .taq/config.json.`,\n\t\t);\n\t\treturn;\n\t}\n\n\tconst taskName = taskArgs.task?.toLowerCase().trim();\n\n\tconst taskHandlers: Record<string, (args: Opts) => Promise<void>> = {\n\t\t'start sandbox': startSandbox,\n\t\t'stop sandbox': stopSandbox,\n\t\t'restart sandbox': restartSandbox,\n\t\t'list protocols': listProtocols,\n\t\t'list-protocols': listProtocols,\n\t\t'show protocols': listProtocols,\n\t\t'show-protocols': listProtocols,\n\t\t'list accounts': listAccounts,\n\t\t'list-accounts': listAccounts,\n\t\t'show accounts': listAccounts,\n\t\t'show-accounts': listAccounts,\n\t\t'bake': bakeBlock,\n\t\t'bake block': bakeBlock,\n\t};\n\n\tconst handler = taskName ? taskHandlers[taskName] : undefined;\n\n\tif (handler) {\n\t\ttry {\n\t\t\tawait handler(taskArgs);\n\t\t} catch (error) {\n\t\t\tawait sendAsyncErr(getErrorMessage(`Error executing task '${taskArgs.task}'`, error));\n\t\t}\n\t} else {\n\t\tawait sendAsyncErr(taskArgs.task ? `Unknown task: ${taskArgs.task}` : 'No task provided');\n\t}\n};\n\nexport default proxy;\n","import { getDockerImage } from '@taqueria/node-sdk';\nimport { Opts } from './types';\n\nexport const TAQ_TEZBOX_IMAGE_ENV_VAR = 'TAQ_TEZBOX_IMAGE';\n\nexport const getDefaultDockerImage = (opts: Opts) => `ghcr.io/tez-capital/tezbox:tezos-v23.1`;\n\nexport const getImage = (opts: Opts) => getDockerImage(getDefaultDockerImage(opts), TAQ_TEZBOX_IMAGE_ENV_VAR);\n"],"mappings":"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","names":["getDockerImage","generateMnemonic","getDockerImage"]}