cli.ts 4.53 KB
Newer Older
Will Cory's avatar
Will Cory committed
1 2 3 4 5 6 7 8
#!/usr/bin/env node
import { cac } from 'cac'
import type { Address } from '@wagmi/core'

import { readOptionsValidators, ReadOptions } from './commands/read'
import * as logger from './lib/logger'
// @ts-ignore it's mad about me importing something not in tsconfig.includes
import packageJson from '../package.json'
Will Cory's avatar
Will Cory committed
9
import { WriteOptions, writeOptionsValidators } from './commands/write'
Will Cory's avatar
Will Cory committed
10 11 12 13 14 15 16 17

const cli = cac('atst')

cli
  .command('read', 'read an attestation')
  .option('--creator <string>', readOptionsValidators.creator.description!)
  .option('--about <string>', readOptionsValidators.about.description!)
  .option('--key <string>', readOptionsValidators.key.description!)
Will Cory's avatar
Will Cory committed
18
  .option('--data-type <string>', readOptionsValidators.dataType.description!, {
Will Cory's avatar
Will Cory committed
19 20
    default: readOptionsValidators.dataType.parse(undefined),
  })
Will Cory's avatar
Will Cory committed
21
  .option('--rpc-url <url>', readOptionsValidators.rpcUrl.description!, {
Will Cory's avatar
Will Cory committed
22 23
    default: readOptionsValidators.rpcUrl.parse(undefined),
  })
Will Cory's avatar
Will Cory committed
24
  .option('--contract <address>', readOptionsValidators.contract.description!, {
Will Cory's avatar
Will Cory committed
25 26 27 28
    default: readOptionsValidators.contract.parse(undefined),
  })
  .example(
    () =>
29
      // note: private key is just the first testing address when running anvil
Will Cory's avatar
Will Cory committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
      `atst read --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --creator 0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3`
  )
  .action(async (options: ReadOptions) => {
    const { read } = await import('./commands/read')

    // TODO use the native api to do this instead of parsing the raw args
    // by default options parses addresses as numbers without precision
    // we should use the args parsing library to do this directly
    // but for now I didn't bother to figure out how to do that
    const { rawArgs } = cli
    const about = rawArgs[rawArgs.indexOf('--about') + 1] as Address
    const creator = rawArgs[rawArgs.indexOf('--creator') + 1] as Address
    const contract = rawArgs.includes('--contract')
      ? (rawArgs[rawArgs.indexOf('--contract') + 1] as Address)
      : options.contract

    await read({ ...options, about, creator, contract })
  })

cli
  .command('write', 'write an attestation')
  .option(
    '--private-key <string>',
    writeOptionsValidators.privateKey.description!
  )
Will Cory's avatar
Will Cory committed
55
  .option('--data-type <string>', readOptionsValidators.dataType.description!, {
Will Cory's avatar
Will Cory committed
56 57
    default: writeOptionsValidators.dataType.parse(undefined),
  })
Will Cory's avatar
Will Cory committed
58 59 60
  .option('--about <string>', writeOptionsValidators.about.description!)
  .option('--key <string>', writeOptionsValidators.key.description!)
  .option('--value <string>', writeOptionsValidators.value.description!)
Will Cory's avatar
Will Cory committed
61
  .option('--rpc-url <url>', writeOptionsValidators.rpcUrl.description!, {
Will Cory's avatar
Will Cory committed
62 63 64
    default: writeOptionsValidators.rpcUrl.parse(undefined),
  })
  .option(
Will Cory's avatar
Will Cory committed
65
    '--contract <address>',
Will Cory's avatar
Will Cory committed
66 67 68 69 70 71 72 73 74
    writeOptionsValidators.contract.description!,
    {
      default: writeOptionsValidators.contract.parse(undefined),
    }
  )
  .example(
    () =>
      `atst write --key "optimist.base-uri" --about 0x2335022c740d17c2837f9C884Bfe4fFdbf0A95D5 --value "my attestation" --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8545`
  )
Will Cory's avatar
Will Cory committed
75
  .action(async (options: WriteOptions) => {
76 77
    const spinner = logger.spinner()
    spinner.start('Writing attestation...')
Will Cory's avatar
Will Cory committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91
    const { write } = await import('./commands/write')

    // TODO use the native api to do this instead of parsing the raw args
    // by default options parses addresses as numbers without precision
    // we should use the args parsing library to do this directly
    // but for now I didn't bother to figure out how to do that
    const { rawArgs } = cli
    const privateKey = rawArgs[rawArgs.indexOf('--private-key') + 1] as Address
    const about = rawArgs[rawArgs.indexOf('--about') + 1] as Address
    const contract = rawArgs.includes('--contract')
      ? (rawArgs[rawArgs.indexOf('--contract') + 1] as Address)
      : options.contract

    await write({ ...options, about, privateKey, contract })
92 93 94 95 96 97 98 99
      .then((res) => {
        spinner.succeed('Attestation written!')
        logger.info(`Attestation hash: ${res}`)
      })
      .catch((e) => {
        logger.error(e)
        spinner.fail('Attestation failed!')
      })
Will Cory's avatar
Will Cory committed
100
  })
Will Cory's avatar
Will Cory committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

cli.version(packageJson.version)

void (async () => {
  try {
    // Parse CLI args without running command
    cli.parse(process.argv, { run: false })
    if (!cli.matchedCommand && cli.args.length === 0) {
      cli.outputHelp()
    }
    await cli.runMatchedCommand()
  } catch (error) {
    logger.error(`\n${(error as Error).message}`)
    process.exit(1)
  }
})()