/** * OpNS commands - register, deregister, lookup. * * Manage OpNS name identity bindings. */ import { getDisplayValue, getOpnsNames, opnsDeregister as opnsDeregisterAction, opnsRegister as opnsRegisterAction, } from '@1sat/actions' import { confirm, isCancel } from '@clack/prompts' import type { GlobalFlags } from '../args' import { extractFlag } from '../args' import { loadContext } from '../context' import { printCommandHelp } from '../help' import { loadKey } from '../keys' import { fatal, formatLabel, formatValue, output } from '../output' export async function handleOpnsCommand( args: string[], opts: GlobalFlags, ): Promise { const [subcommand, ...rest] = args switch (subcommand) { case 'register': return opnsRegister(rest, opts) case 'deregister': return opnsDeregister(rest, opts) case 'lookup': return opnsLookup(rest, opts) default: printCommandHelp('opns', opts.json) if (subcommand && subcommand !== 'help') { process.exit(1) } } } async function opnsRegister(args: string[], opts: GlobalFlags): Promise { const outpoint = extractFlag(args, '--outpoint') if (!outpoint) fatal('Missing --outpoint ') if (!opts.yes) { const ok = await confirm({ message: `Register identity on OpNS name ${outpoint}?`, }) if (isCancel(ok) || !ok) { fatal('Registration cancelled.') } } const privateKey = await loadKey() const { ctx, destroy } = await loadContext(privateKey, { chain: opts.chain, }) try { // Look up the OpNS ordinal from the wallet const namesResult = await getOpnsNames.execute(ctx, { limit: 10000 }) const ordinal = namesResult.outputs.find((o) => o.outpoint === outpoint) if (!ordinal) { fatal(`OpNS name not found in wallet: ${outpoint}`) } const result = await opnsRegisterAction.execute(ctx, { ordinal, inputBEEF: namesResult.BEEF as number[] | undefined, }) if (result.error) { fatal(result.error) } output(opts.json ? result : { txid: result.txid }, opts) } finally { await destroy() } } async function opnsDeregister( args: string[], opts: GlobalFlags, ): Promise { const outpoint = extractFlag(args, '--outpoint') if (!outpoint) fatal('Missing --outpoint ') if (!opts.yes) { const ok = await confirm({ message: `Deregister identity from OpNS name ${outpoint}?`, }) if (isCancel(ok) || !ok) { fatal('Deregistration cancelled.') } } const privateKey = await loadKey() const { ctx, destroy } = await loadContext(privateKey, { chain: opts.chain, }) try { // Look up the OpNS ordinal from the wallet const namesResult = await getOpnsNames.execute(ctx, { limit: 10000 }) const ordinal = namesResult.outputs.find((o) => o.outpoint === outpoint) if (!ordinal) { fatal(`OpNS name not found in wallet: ${outpoint}`) } const result = await opnsDeregisterAction.execute(ctx, { ordinal, inputBEEF: namesResult.BEEF as number[] | undefined, }) if (result.error) { fatal(result.error) } output(opts.json ? result : { txid: result.txid }, opts) } finally { await destroy() } } async function opnsLookup(_args: string[], opts: GlobalFlags): Promise { const privateKey = await loadKey() const { ctx, destroy } = await loadContext(privateKey, { chain: opts.chain, }) try { const result = await getOpnsNames.execute(ctx, { limit: 100 }) if (opts.json) { output(result.outputs, opts) return } if (result.outputs.length === 0) { output('No OpNS names found.', opts) return } for (const o of result.outputs) { const nameTag = getDisplayValue(o, 'name', 'name') ?? '' const publishedTag = o.tags?.find((t) => t === 'opns:published') const status = publishedTag ? 'registered' : 'unregistered' console.log( ` ${formatValue(o.outpoint)} ${nameTag ? formatValue(nameTag) : ''} ${formatLabel(status)}`, ) } console.log(`\n ${result.outputs.length} OpNS name(s) found.`) } finally { await destroy() } }