diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt index b478ef8b85..90ca163159 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt @@ -470,11 +470,22 @@ class Context( * accept the exact same identifier formats. Throws on unrecognised input — * command handlers catch [IllegalArgumentException] at the top level and * translate to `{"error": "bad_args"}`. + * + * A pubkey is always 32 bytes, so we require exactly 64 hex chars: the shared + * resolver's fallback runs a lenient `Hex.decode` that turns a short + * bech32/hex-ish word (e.g. a mistyped verb like `sync`) into a bogus few-byte + * "pubkey" instead of failing — this rejects that so a bad OBSERVER/USER errors + * cleanly rather than silently scoring/fetching garbage. */ - suspend fun requireUserHex(input: String): com.vitorpamplona.quartz.nip01Core.core.HexKey = - com.vitorpamplona.quartz.nip05DnsIdentifiers - .resolveUserHexOrNull(input, nip05Client) - ?: throw IllegalArgumentException("Could not resolve user: '$input' (accepts npub, nprofile, 64-hex, or name@domain.tld)") + suspend fun requireUserHex(input: String): com.vitorpamplona.quartz.nip01Core.core.HexKey { + val notResolved = "Could not resolve user: '$input' (accepts npub, nprofile, 64-hex, or name@domain.tld)" + val hex = + com.vitorpamplona.quartz.nip05DnsIdentifiers + .resolveUserHexOrNull(input, nip05Client) + ?: throw IllegalArgumentException(notResolved) + require(hex.length == 64) { notResolved } + return hex + } /** * Outbox / NIP-65 write relays for this account. Read from the diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt index 121ee79953..302fc6d02e 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GrapeRankCommand.kt @@ -85,7 +85,6 @@ import kotlin.math.roundToInt * - `amy graperank crawl [OBSERVER]` — network only: crawl the reachable graph's * kind 3/10000/1984/10002 into the local store. Idempotent and cumulative, so * run it a few times to make sure everything is loaded. Scores nothing. - * (`sync` is a deprecated alias — it warns and will be removed.) * - `amy graperank status` — read-only inventory of all of the above: WoT record * counts, reachability-cache freshness, operator state, persisted card sets. * Answers "do I need to crawl again?" with no network and no signing. @@ -210,17 +209,6 @@ object GrapeRankCommand { "providers" -> providers(dataDir, tail.drop(1).toTypedArray()) "operator" -> operator(dataDir, tail.drop(1).toTypedArray()) "crawl" -> crawl(dataDir, tail.drop(1).toTypedArray()) - // Deprecated pre-rename alias for `crawl`. Actively misleading now that - // the negentropy record refresh is `graperank refresh` (and `amy sync` - // is the generic negentropy verb), so it warns before it runs — next - // step is removal. - "sync" -> { - System.err.println( - "[graperank] `graperank sync` is deprecated and will be removed — use `graperank crawl` " + - "(or `graperank refresh` to re-sync known authors' records).", - ) - crawl(dataDir, tail.drop(1).toTypedArray()) - } "status" -> status(dataDir) // The relay census outgrew graperank (it feeds the shared NIP-66 // reachability cache every command reads) and moved to `amy relay