process#exit TypeScript Examples

The following examples show how to use process#exit. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: main.ts    From ng-chrome-extension with MIT License 6 votes vote down vote up
main = (args: string[]) => {
  const argument = [...args].shift();

  if (requestVersion(String(argument))) {
    const { version } = require('../package.json');
    console.log(version);
    exit(0);
  }
  const container = createContainer();

  if (requestHelp(String(argument))) {
    container.get<LogService>('LogService').info('https://github.com/larscom/ng-chrome-extension');
    exit(0);
  }

  container.get<CLI>('CLI').run();
}
Example #2
Source File: terraform-fmt.ts    From airnode with MIT License 6 votes vote down vote up
exec(BINARY_TEST, (err, _stdout, _stderr) => {
  if (err) {
    logger.log('Missing Terraform binary, skipping formatting.');
    exit();
  }

  if (command === 'check') {
    exec(CMD_CHECK, (err, stdout, stderr) => {
      failOnError('Failed to list Terraform formatting issues', err, stderr);

      if (stdout) {
        logger.log('Found unformatted TF files:');
        logger.log(stdout);
        // We have unformatted files, we have to fail
        exit(EC_FORMATTING);
      }

      logger.log('All TF files formatted correctly!');
      exit();
    });
  }

  if (command === 'write') {
    exec(CMD_WRITE, (err, stdout, stderr) => {
      failOnError('Failed to correct Terraform formatting issues', err, stderr);

      if (stdout) {
        logger.log('Fixed formatting of the following TF files:');
        logger.log(stdout);
      } else {
        logger.log('All TF files already formatted correctly, nothing to do');
      }
      exit();
    });
  }
});
Example #3
Source File: index.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Displays an interactive stamp picker to select a Stamp ID.
 *
 * A typical use case is to prompt the user for a stamp, when
 * the command requires one, but was not specified in `argv`.
 *
 * Makes a request via `bee` to fetch possible stamps.
 *
 * @returns {Promise<string>} Hex representation of the Stamp ID.
 */
export async function pickStamp(beeDebug: BeeDebug, console: CommandLog): Promise<string> {
  const stamps = ((await beeDebug.getAllPostageBatch()) || []).map(enrichStamp)

  if (!stamps.length) {
    console.error('You need to have at least one stamp for this action.')
    exit(1)
  }

  const choices = stamps.map(stamp => `${stamp.batchID} (${stamp.usageText})`)
  const value = await console.promptList(choices, 'Please select a stamp for this action')
  const [hex] = value.split(' ')

  return hex
}
Example #4
Source File: index.ts    From epicgames-freegames-node with MIT License 6 votes vote down vote up
export async function main(): Promise<void> {
  if (process.env.NODE_ENV !== 'test') {
    await checkForUpdate();
    if (config.testNotifiers) {
      await testNotifiers();
    }
    const accountPromises = config.accounts.map(redeemAccount);
    await Promise.all(accountPromises);
    exit(0); // For some reason, puppeteer will keep a zombie promise alive and stop Node from exiting
  }
}
Example #5
Source File: upload.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private async maybeRunSizeChecks(): Promise<void> {
    if (this.yes) {
      return
    }
    const { size } = await this.getUploadableInfo()

    if (size < MAX_UPLOAD_SIZE) {
      return
    }

    const message = `Size is larger than the recommended maximum value of ${(MAX_UPLOAD_SIZE / 1e6).toFixed(
      2,
    )} megabytes`

    if (this.quiet) {
      throw new CommandLineError(Message.requireOptionConfirmation('yes', message))
    }

    const confirmation = await this.console.confirm(message + ' Do you want to proceed?')

    if (!confirmation) {
      exit(1)
    }
  }
Example #6
Source File: feed-command.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private async getIdentity(): Promise<Identity> {
    const { identities } = this.commandConfig.config

    if (this.identity && !identities[this.identity]) {
      if (this.quiet) {
        this.console.error('The provided identity does not exist.')
        exit(1)
      }
      this.console.error('The provided identity does not exist. Please select one that exists.')
    }

    return identities[this.identity] || identities[await pickIdentity(this.commandConfig, this.console)]
  }
Example #7
Source File: print.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private async getAddressString(): Promise<string> {
    const identity = this.commandConfig.config.identities[this.identity]

    if (!identity) {
      this.console.error('No such identity')
      exit(1)
    }

    if (identity) {
      if (this.password) {
        const wallet = await this.getWallet()

        return wallet.getAddressString()
      } else {
        return this.getAddressStringFromIdentity(identity)
      }
    }

    return this.identity
  }
Example #8
Source File: print.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private getAddressStringFromIdentity(identity: Identity): string {
    const { wallet, identityType } = identity

    if (isV3Wallet(wallet, identityType)) {
      if (!wallet.address) {
        this.console.error('No address in V3 wallet, please provide password so it can be decrypted.')
        exit(1)
      }

      return wallet.address
    } else if (isSimpleWallet(wallet, identityType)) {
      const ethereumWallet = Wallet.fromPrivateKey(Buffer.from(wallet.privateKey, 'hex'))

      return ethereumWallet.getAddressString()
    } else {
      this.console.error('Address type is not supported.')
      exit(1)
    }
  }
Example #9
Source File: remove.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
public async run(): Promise<void> {
    await super.init()
    const { name } = await this.getOrPickIdentity(this.identityName)

    if (!this.yes) {
      if (this.quiet) {
        throw new CommandLineError(
          Message.requireOptionConfirmation('yes', 'This will delete the identity with no way to recover it'),
        )
      }
      const confirmation = await this.console.confirmAndDelete(`Are you sure you want delete the identity '${name}'?`)

      if (!confirmation) {
        this.console.log('Aborted')
        exit(0)
      }
    }

    this.commandConfig.removeIdentity(name)
    this.console.log(`Identity '${name}' has been successfully deleted`)
  }
Example #10
Source File: show.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
private async maybePromptForSensitive(): Promise<void | never> {
    if (this.yes) {
      return
    }

    if (this.quiet && !this.yes) {
      throw new CommandLineError(
        Message.requireOptionConfirmation('yes', 'This will print sensitive information to the console'),
      )
    }

    if (!(await this.console.confirmAndDelete('This will print sensitive information to the console. Continue?'))) {
      exit(0)
    }
  }
Example #11
Source File: pinning-command.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
protected async init(): Promise<void> {
    await super.init()

    if (isGateway(this.beeApiUrl)) {
      this.console.error('Pinning is currently not supported on the gateway node.')
      this.console.error('You can use the pinning API with your local Bee node.')

      exit(1)
    }
  }
Example #12
Source File: send.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
public async run(): Promise<void> {
    await super.init()

    if (this.path) {
      if (!fileExists(this.path)) {
        this.console.error('There is no file at the specified path')
        exit(1)
      }
      this.sendable = readFileSync(this.path)
    } else {
      this.sendable = this.message
    }

    const length = getByteSize(this.sendable)

    if (length > 4000) {
      this.console.error('Maximum payload size is 4000 bytes.')
      this.console.error('You tried sending ' + length + ' bytes.')
      exit(1)
    }

    if (!this.stamp) {
      this.stamp = await pickStamp(this.beeDebug, this.console)
    }

    this.console.log('Sending PSS message on topic ' + this.topic)

    await this.bee.pssSend(this.stamp, this.topic, this.target, this.sendable, this.recipient)
    this.console.log('Message sent successfully.')
  }
Example #13
Source File: command-config.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/** Load configuration from config path or creates config folder */
  private prepareConfig() {
    if (!existsSync(this.configFilePath)) {
      if (!existsSync(this.configFolderPath)) mkdirSync(this.configFolderPath, { mode: 0o700, recursive: true })

      //save config initialized in constructor
      this.saveConfig()
    } else {
      //load config
      const configData = readFileSync(this.configFilePath)
      try {
        this.config = JSON.parse(configData.toString())
      } catch (err) {
        this.console.error(
          `There has been an error parsing JSON configuration of CLI from path: '${this.configFilePath}'`,
        )

        exit(1)
      }
    }
  }
Example #14
Source File: list.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
public async run(): Promise<void> {
    await super.init()
    this.console.verbose(`Listing postage stamps...`)

    const stamps = (await this.beeDebug.getAllPostageBatch()) || []

    if (stamps.length === 0) {
      this.console.error('You do not have any stamps.')
      exit(1)
    }

    const enrichedStamps = stamps.map(enrichStamp)

    const filteredStamps = enrichedStamps.filter(x => x.usageNormal >= this.minUsage && x.usageNormal <= this.maxUsage)

    if (filteredStamps.length === 0) {
      exit(1)
    }

    const limitedStamps = filteredStamps.slice(0, this.limit)

    const orderedStamps = this.leastUsed ? limitedStamps.sort((a, b) => a.usage - b.usage) : limitedStamps

    printDivided(
      orderedStamps,
      (items: EnrichedStamp, console: CommandLog) => {
        printStamp(items, console, !this.hideUsage)
      },
      this.console,
    )
  }
Example #15
Source File: 3-runAssignments.ts    From double-agent with MIT License 5 votes vote down vote up
runAssignments(runnerFactory, userAgentsToTestPath, dataDir)
  .then(() => process.exit())
  .catch(console.log);
Example #16
Source File: upload.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
   * Waits until the data syncing is successful on Swarm network
   *
   * @param tag had to be attached to the uploaded file
   *
   * @returns whether the file sync was successful or not.
   */
  private async waitForFileSynced(tag: Tag): Promise<void | never> {
    const tagUid = tag.uid
    const pollingTime = this.syncPollingTime
    const pollingTrials = this.syncPollingTrials
    let synced = false
    let syncStatus = 0
    const progressBar = new SingleBar({ clearOnComplete: true }, Presets.rect)

    if (this.verbosity !== VerbosityLevel.Quiet && !this.curl) {
      progressBar.start(tag.total, 0)
    }
    for (let i = 0; i < pollingTrials; i++) {
      tag = await this.bee.retrieveTag(tagUid)

      if (syncStatus !== tag.synced) {
        i = 0
        syncStatus = tag.synced
      }

      if (this.curl) {
        this.console.log(`${syncStatus} / ${tag.total}`)
      } else {
        progressBar.update(syncStatus)
      }

      if (syncStatus >= tag.total) {
        synced = true
        break
      }
      await sleep(pollingTime)
    }
    progressBar.stop()

    if (synced) {
      this.console.dim('Data has been synced on Swarm network')
    } else {
      this.console.error('Data syncing timeout.')
      exit(1)
    }
  }
Example #17
Source File: upload.ts    From swarm-cli with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
// eslint-disable-next-line complexity
  public async run(usedFromOtherCommand = false): Promise<void> {
    await super.init()

    if (this.hasUnsupportedGatewayOptions()) {
      exit(1)
    }

    await this.maybePrintSyncWarning()

    if (!this.stdin && !FS.existsSync(this.path)) {
      throw new CommandLineError(`Given filepath '${this.path}' doesn't exist`)
    }

    if (this.stdin) {
      if (!this.stamp) {
        throw new CommandLineError('Stamp must be passed when reading data from stdin')
      }
      this.stdinData = await readStdin(this.console)
    }

    if (!this.stamp) {
      if (isGateway(this.beeApiUrl)) {
        this.stamp = '0'.repeat(64)
      } else {
        this.stamp = await pickStamp(this.beeDebug, this.console)
      }
    }

    await this.maybeRunSizeChecks()

    const tag = this.sync ? await this.bee.createTag() : undefined

    const uploadingFolder = !this.stdin && FS.statSync(this.path).isDirectory()

    if (uploadingFolder && !this.indexDocument && fileExists(join(this.path, 'index.html'))) {
      this.console.info('Setting --index-document to index.html')
      this.indexDocument = 'index.html'
    }

    const url = await this.uploadAnyWithSpinner(tag, uploadingFolder)

    this.console.dim('Data has been sent to the Bee node successfully!')
    this.console.log(createKeyValue('Swarm hash', this.hash))
    this.console.dim('Waiting for file chunks to be synced on Swarm network...')

    if (this.sync && tag) {
      await this.waitForFileSynced(tag)
    }

    this.console.dim('Uploading was successful!')
    this.console.log(createKeyValue('URL', url))

    if (!this.encrypt && url.includes('/bzz/')) {
      const swarmCid = encodeManifestReference(this.hash)
      this.console.log(createKeyValue('Bzz.link', `https://${swarmCid.toString()}.bzz.link`))
    }

    if (!usedFromOtherCommand) {
      this.console.quiet(this.hash)

      if (!isGateway(this.beeApiUrl) && !this.quiet && this.debugApiIsUsable()) {
        printEnrichedStamp(await this.beeDebug.getPostageBatch(this.stamp), this.console)
      }
    }
  }
Example #18
Source File: index.ts    From epicgames-freegames-node with MIT License 5 votes vote down vote up
main().catch((err) => {
  logger.error(err);
  logVersionOnError();
  exit(1);
});
Example #19
Source File: console.ts    From bdk with Apache License 2.0 5 votes vote down vote up
exit(0)
Example #20
Source File: terraform-fmt.ts    From airnode with MIT License 5 votes vote down vote up
function failOnError(message: string, err: ExecException | null, stderr: string) {
  if (err) {
    logger.error(message);
    logger.error(err.message);
    logger.error(stderr);
    exit(EC_TERRAFORM);
  }
}
Example #21
Source File: cli.ts    From airnode with MIT License 4 votes vote down vote up
yargs
  .command(
    'derive-airnode-xpub',
    'Derives the Airnode extended public key',
    {
      'airnode-mnemonic': airnodeMnemonic,
    },
    async (args) => {
      const xpub = await admin.deriveAirnodeXpub(args['airnode-mnemonic']);
      logger.log(`Airnode xpub: ${xpub}`);
    }
  )
  .command(
    'verify-airnode-xpub',
    'Verifies that the xpub belongs to the Airnode wallet',
    {
      'airnode-xpub': airnodeXpub,
      'airnode-address': airnodeAddress,
    },
    async (args) => {
      try {
        admin.verifyAirnodeXpub(args['airnode-xpub'], args['airnode-address']);
        logger.log(`Airnode xpub is: VALID`);
      } catch {
        logger.error(`Airnode xpub is: INVALID`);
      }
    }
  )
  .command(
    'derive-sponsor-wallet-address',
    'Derives the address of the wallet for an airnode-sponsor pair',
    {
      'airnode-xpub': airnodeXpub,
      'airnode-address': airnodeAddress,
      'sponsor-address': sponsorAddress,
    },
    async (args) => {
      const sponsorWalletAddress = await admin.deriveSponsorWalletAddress(
        args['airnode-xpub'],
        args['airnode-address'],
        args['sponsor-address']
      );
      logger.log(`Sponsor wallet address: ${sponsorWalletAddress}`);
    }
  )
  .command(
    'sponsor-requester',
    'Allows a requester to make requests that will be fulfilled by the Airnode using the sponsor wallet',
    {
      ...airnodeRrpCommands,
      ...sponsorWallet,
      'requester-address': requesterAddress,
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
        signer: { mnemonic: args['sponsor-mnemonic'], derivationPath: args['derivation-path'] },
      });
      const requesterAddress = await admin.sponsorRequester(airnodeRrp, args['requester-address'], overrides);
      logger.log(`Requester address ${requesterAddress} is now sponsored by ${await airnodeRrp.signer.getAddress()}`);
    }
  )
  .command(
    'unsponsor-requester',
    'Disallow a requester to make requests to the Airnode',
    {
      ...airnodeRrpCommands,
      ...sponsorWallet,
      'requester-address': requesterAddress,
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
        signer: { mnemonic: args['sponsor-mnemonic'], derivationPath: args['derivation-path'] },
      });
      const requesterAddress = await admin.unsponsorRequester(airnodeRrp, args['requester-address'], overrides);
      logger.log(
        `Requester address ${requesterAddress} is no longer sponsored by ${await airnodeRrp.signer.getAddress()}`
      );
    }
  )
  .command(
    'get-sponsor-status',
    'Returns the sponsorship status for the given sponsor and requester',
    {
      ...airnodeRrpCommands,
      'sponsor-address': sponsorAddress,
      'requester-address': requesterAddress,
    },
    async (args) => {
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
      });
      const status = await admin.sponsorToRequesterToSponsorshipStatus(
        airnodeRrp,
        args['sponsor-address'],
        args['requester-address']
      );
      logger.log(`Requester address sponsored: ${status}`);
    }
  )
  .command(
    'create-template',
    'Creates a template and returns its ID',
    {
      ...airnodeRrpCommands,
      ...userWallet,
      'template-file-path': {
        type: 'string',
        demandOption: true,
        describe: 'Path of the template JSON file',
      },
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const template = JSON.parse(fs.readFileSync(args['template-file-path']).toString());
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
        signer: { mnemonic: args.mnemonic, derivationPath: args['derivation-path'] },
      });
      const templateId = await admin.createTemplate(airnodeRrp, template, overrides);
      logger.log(`Template ID: ${templateId}`);
    }
  )
  .command(
    'get-template',
    'Returns the template for the given template-id',
    {
      ...airnodeRrpCommands,
      'template-id': {
        type: 'string',
        demandOption: true,
        describe: 'Onchain ID of the template',
      },
    },
    async (args) => {
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
      });
      const parameters = await admin.getTemplate(airnodeRrp, args['template-id']);
      logger.log(toJSON(parameters));
    }
  )
  .command(
    'request-withdrawal',
    'Requests withdrawal from the designated wallet of an Airnode as a sponsor',
    {
      ...airnodeRrpCommands,
      ...sponsorWallet,
      'airnode-address': airnodeAddress,
      'sponsor-wallet-address': sponsorWalletAddress,
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
        signer: { mnemonic: args['sponsor-mnemonic'], derivationPath: args['derivation-path'] },
      });

      const withdrawalRequestId = await admin.requestWithdrawal(
        airnodeRrp,
        args['airnode-address'],
        args['sponsor-wallet-address'],
        overrides
      );
      logger.log(`Withdrawal request ID: ${withdrawalRequestId}`);
    }
  )
  .command(
    'check-withdrawal-request',
    'Checks the state of the withdrawal request',
    {
      ...airnodeRrpCommands,
      'withdrawal-request-id': withdrawalRequestId,
    },
    async (args) => {
      const airnodeRrp = await evm.getAirnodeRrp(args['provider-url'], {
        airnodeRrpAddress: args['airnode-rrp-address'],
      });
      const response = await admin.checkWithdrawalRequest(airnodeRrp, args['withdrawal-request-id']);
      if (response) {
        logger.log(`Withdrawn amount: ${response.amount}`);
      } else {
        logger.log(`Withdrawal request is not fulfilled yet`);
      }
    }
  )
  .command(
    'derive-endpoint-id',
    'Derives an endpoint ID using the OIS title and endpoint name',
    {
      'ois-title': {
        type: 'string',
        demandOption: true,
        describe: 'Title of the OIS that the endpoint belongs to',
      },
      'endpoint-name': {
        type: 'string',
        demandOption: true,
        describe: 'Name of the endpoint',
      },
    },
    async (args) => {
      const endpointId = await admin.deriveEndpointId(args['ois-title'], args['endpoint-name']);
      logger.log(`Endpoint ID: ${endpointId}`);
    }
  )
  .command(
    'set-whitelist-expiration',
    'Sets whitelist expiration of a requester for the Airnode–endpoint pair',
    {
      ...requesterAuthorizerWithAirnodeCommands,
      ...userWallet,
      'airnode-address': airnodeAddress,
      'expiration-timestamp': expirationTimestamp,
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const requesterAuthorizerWithAirnode = await evm.getRequesterAuthorizerWithAirnode(args['provider-url'], {
        requesterAuthorizerWithAirnodeAddress: args['requester-authorizer-with-airnode-address'],
        signer: { mnemonic: args.mnemonic, derivationPath: args['derivation-path'] },
      });

      await admin.setWhitelistExpiration(
        requesterAuthorizerWithAirnode,
        args['airnode-address'],
        args['endpoint-id'],
        args['requester-address'],
        args['expiration-timestamp'],
        overrides
      );
      logger.log(
        `Whitelist expiration: ${new Date(args['expiration-timestamp']).toUTCString()} (${
          args['expiration-timestamp']
        })`
      );
    }
  )
  .command(
    'extend-whitelist-expiration',
    'Extends whitelist expiration of a requester for the Airnode–endpoint pair',
    {
      ...requesterAuthorizerWithAirnodeCommands,
      ...userWallet,
      'airnode-address': airnodeAddress,
      'expiration-timestamp': expirationTimestamp,
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const requesterAuthorizerWithAirnode = await evm.getRequesterAuthorizerWithAirnode(args['provider-url'], {
        requesterAuthorizerWithAirnodeAddress: args['requester-authorizer-with-airnode-address'],
        signer: { mnemonic: args.mnemonic, derivationPath: args['derivation-path'] },
      });
      await admin.extendWhitelistExpiration(
        requesterAuthorizerWithAirnode,
        args['airnode-address'],
        args['endpoint-id'],
        args['requester-address'],
        args['expiration-timestamp'],
        overrides
      );
      logger.log(
        `Whitelist expiration: ${new Date(args['expiration-timestamp']).toUTCString()} (${
          args['expiration-timestamp']
        })`
      );
    }
  )
  .command(
    'set-indefinite-whitelist-status',
    'Sets the indefinite whitelist status of a requester for the Airnode–endpoint pair',
    {
      ...requesterAuthorizerWithAirnodeCommands,
      ...userWallet,
      'airnode-address': airnodeAddress,
      'indefinite-whitelist-status': indefiniteWhitelistStatus,
      ...transactionOverrides,
    },
    async (args) => {
      const overrides = admin.parseCliOverrides(args);
      const requesterAuthorizerWithAirnode = await evm.getRequesterAuthorizerWithAirnode(args['provider-url'], {
        requesterAuthorizerWithAirnodeAddress: args['requester-authorizer-with-airnode-address'],
        signer: { mnemonic: args.mnemonic, derivationPath: args['derivation-path'] },
      });
      await admin.setIndefiniteWhitelistStatus(
        requesterAuthorizerWithAirnode,
        args['airnode-address'],
        args['endpoint-id'],
        args['requester-address'],
        args['indefinite-whitelist-status'],
        overrides
      );
      logger.log(`Whitelist status: ${args['indefinite-whitelist-status']}`);
    }
  )
  .command(
    'get-whitelist-status',
    'Returns the detailed whitelist status of a requester for the Airnode–endpoint pair',
    {
      ...requesterAuthorizerWithAirnodeCommands,
      'airnode-address': airnodeAddress,
    },
    async (args) => {
      const requesterAuthorizerWithAirnode = await evm.getRequesterAuthorizerWithAirnode(args['provider-url'], {
        requesterAuthorizerWithAirnodeAddress: args['requester-authorizer-with-airnode-address'],
      });
      const whitelistStatus = await admin.getWhitelistStatus(
        requesterAuthorizerWithAirnode,
        args['airnode-address'],
        args['endpoint-id'],
        args['requester-address']
      );
      logger.log(toJSON(whitelistStatus));
    }
  )
  .command(
    'is-requester-whitelisted',
    'Returns a boolean to indicate whether or not the requester is whitelisted to use the Airnode–endpoint pair',
    {
      ...requesterAuthorizerWithAirnodeCommands,
      'airnode-address': airnodeAddress,
    },
    async (args) => {
      const requesterAuthorizerWithAirnode = await evm.getRequesterAuthorizerWithAirnode(args['provider-url'], {
        requesterAuthorizerWithAirnodeAddress: args['requester-authorizer-with-airnode-address'],
      });
      const isRequesterWhitelisted = await admin.isRequesterWhitelisted(
        requesterAuthorizerWithAirnode,
        args['airnode-address'],
        args['endpoint-id'],
        args['requester-address']
      );
      logger.log(`Is requester whitelisted: ${isRequesterWhitelisted}`);
    }
  )
  .command(
    'generate-mnemonic',
    'Generates a random mnemonic. Uses "ethers.Wallet.createRandom" under the hood',
    async () => {
      const mnemonic = await admin.generateMnemonic();
      const airnodeAddress = await admin.deriveAirnodeAddress(mnemonic);
      const airnodeXpub = admin.deriveAirnodeXpub(mnemonic);

      logger.log(
        [
          'This mnemonic is created locally on your machine using "ethers.Wallet.createRandom" under the hood.',
          'Make sure to back it up securely, e.g., by writing it down on a piece of paper:',
          '',
          mnemonic,
          '',
          `The Airnode address for this mnemonic is: ${airnodeAddress}`,
          `The Airnode xpub for this mnemonic is: ${airnodeXpub}`,
          '',
        ].join('\n')
      );
    }
  )
  .command(
    'derive-airnode-address',
    'Derives the airnode address which is the identifier of the particular Airnode on chain',
    { 'airnode-mnemonic': airnodeMnemonic },
    async (args) => {
      const airnodeAddress = await admin.deriveAirnodeAddress(args['airnode-mnemonic']);
      logger.log(`Airnode address: ${airnodeAddress}`);
    }
  )
  .example(cliExamples.map((line) => [`$0 ${line}\n`]))
  .demandCommand(1)
  .strict()
  .fail((message, err) => {
    logger.error(message ? message : `Command failed with unexpected error:\n\n${err.message}`);

    exit(1);
  })
  .help()
  .wrap(120).argv;