fix(marmot-interop): robust pubkey extraction from wn output
wn prints either JSON (with --json) or a yaml-ish "key: value" pretty
form depending on the command and build. On the user's macOS run,
create-identity printed yaml ("pubkey: npub1..."), the subsequent
wn --json whoami didn't return the expected JSON shape, and
ensure_identity bailed with "could not determine npub for B".
Add a shared extract_pubkey helper in lib.sh that tries, in order:
1. JSON object .pubkey / .npub / .public_key
2. JSON array .[0].pubkey / .[0].npub / .[0].public_key
3. yaml-ish "pubkey: ..." via sed
4. yaml-ish "npub: ..." via sed
ensure_identity and prompt_for_a_npub now use it, and also fall back
to the non-JSON whoami output if --json returns nothing. On total
failure, the raw output is echoed to the log for diagnosis.
Also made npub_to_hex best-effort with the same double-try approach.
When hex lookup fails, it returns the npub unchanged — downstream
expect_contains assertions work against either form since wn's own
group listings may use either encoding.
https://claude.ai/code/session_01PacmbE1KKWMSRmDw3bnCNo
This commit is contained in:
@@ -212,16 +212,42 @@ wait_for_member() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------- npub <-> hex conversion helpers -------------------------------------
|
# ------- output parsing ------------------------------------------------------
|
||||||
# whitenoise's `wn` accepts both, but we use hex internally for JSON comparisons.
|
# `wn` prints either JSON (with --json) or a yaml-ish "key: value" pretty form.
|
||||||
# We rely on `wn debug` (or fall back to a python one-liner) — but to keep zero
|
# This helper extracts the pubkey (npub) from whichever form we got.
|
||||||
# extra deps we do the conversion via wn itself by round-tripping through
|
extract_pubkey() {
|
||||||
# `wn users show <npub>` which prints both forms.
|
local raw="$1" v=""
|
||||||
|
# JSON: single object
|
||||||
|
v=$(printf '%s' "$raw" | jq -r '.pubkey // .npub // .public_key // empty' 2>/dev/null || true)
|
||||||
|
if [[ -n "$v" && "$v" != "null" ]]; then printf '%s' "$v"; return; fi
|
||||||
|
# JSON: array of accounts (whoami may return a list)
|
||||||
|
v=$(printf '%s' "$raw" | jq -r '.[0].pubkey // .[0].npub // .[0].public_key // empty' 2>/dev/null || true)
|
||||||
|
if [[ -n "$v" && "$v" != "null" ]]; then printf '%s' "$v"; return; fi
|
||||||
|
# yaml-ish "pubkey: npub1..."
|
||||||
|
v=$(printf '%s\n' "$raw" | sed -n 's/^[[:space:]]*pubkey[[:space:]]*:[[:space:]]*//p' | head -n1)
|
||||||
|
if [[ -n "$v" ]]; then printf '%s' "$v"; return; fi
|
||||||
|
# yaml-ish "npub: npub1..." (alternative key)
|
||||||
|
v=$(printf '%s\n' "$raw" | sed -n 's/^[[:space:]]*npub[[:space:]]*:[[:space:]]*//p' | head -n1)
|
||||||
|
if [[ -n "$v" ]]; then printf '%s' "$v"; return; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Best-effort npub -> hex conversion via `wn users show`. If the lookup fails
|
||||||
|
# (e.g. --json not supported or user not resolvable), returns the input
|
||||||
|
# unchanged — downstream comparisons tolerate either form.
|
||||||
npub_to_hex() {
|
npub_to_hex() {
|
||||||
local npub="$1"
|
local npub="$1" raw hex
|
||||||
wn_b --json users show "$npub" 2>/dev/null \
|
raw=$(wn_b --json users show "$npub" 2>/dev/null || true)
|
||||||
| jq -r '.pubkey // .public_key // empty' 2>/dev/null \
|
hex=$(printf '%s' "$raw" | jq -r '.pubkey // .public_key // .hex // empty' 2>/dev/null || true)
|
||||||
|| printf '%s' "$npub"
|
if [[ -z "$hex" || "$hex" == "null" ]]; then
|
||||||
|
# fallback to yaml-ish output
|
||||||
|
raw=$(wn_b users show "$npub" 2>/dev/null || true)
|
||||||
|
hex=$(printf '%s\n' "$raw" | sed -n 's/^[[:space:]]*\(public_key\|hex\)[[:space:]]*:[[:space:]]*//p' | head -n1)
|
||||||
|
fi
|
||||||
|
if [[ -n "$hex" && "$hex" != "null" ]]; then
|
||||||
|
printf '%s' "$hex"
|
||||||
|
else
|
||||||
|
printf '%s' "$npub"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------- state file ----------------------------------------------------------
|
# ------- state file ----------------------------------------------------------
|
||||||
|
|||||||
@@ -145,24 +145,43 @@ ensure_identity() {
|
|||||||
local who="$1" cmd
|
local who="$1" cmd
|
||||||
if [[ "$who" == "B" ]]; then cmd=wn_b; else cmd=wn_c; fi
|
if [[ "$who" == "B" ]]; then cmd=wn_b; else cmd=wn_c; fi
|
||||||
step "ensuring Identity $who"
|
step "ensuring Identity $who"
|
||||||
local npub
|
|
||||||
npub=$("$cmd" --json whoami 2>/dev/null | jq -r '.pubkey // .npub // empty' 2>/dev/null || true)
|
# First try whoami (will be empty if no account yet). Try --json, then the
|
||||||
if [[ -z "${npub:-}" || "$npub" == "null" ]]; then
|
# yaml-ish pretty form as a fallback.
|
||||||
info "creating new identity for $who"
|
local out npub=""
|
||||||
"$cmd" create-identity 2>&1 | tee -a "$LOG_FILE" >&2
|
out=$("$cmd" --json whoami 2>/dev/null || true)
|
||||||
npub=$("$cmd" --json whoami 2>/dev/null | jq -r '.pubkey // .npub // empty' || true)
|
npub=$(extract_pubkey "$out")
|
||||||
fi
|
|
||||||
if [[ -z "${npub:-}" ]]; then
|
if [[ -z "${npub:-}" ]]; then
|
||||||
fail_msg "could not determine npub for $who"; exit 1
|
out=$("$cmd" whoami 2>/dev/null || true)
|
||||||
|
npub=$(extract_pubkey "$out")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${npub:-}" ]]; then
|
||||||
|
info "creating new identity for $who"
|
||||||
|
out=$("$cmd" create-identity 2>&1 | tee -a "$LOG_FILE")
|
||||||
|
npub=$(extract_pubkey "$out")
|
||||||
|
# Some builds only print the npub on whoami after create, not on
|
||||||
|
# create-identity itself — re-query as a last resort.
|
||||||
|
if [[ -z "${npub:-}" ]]; then
|
||||||
|
out=$("$cmd" whoami 2>/dev/null || true)
|
||||||
|
npub=$(extract_pubkey "$out")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${npub:-}" ]]; then
|
||||||
|
fail_msg "could not determine npub for $who — raw output below:"
|
||||||
|
printf '%s\n' "$out" | tee -a "$LOG_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
local hex
|
local hex
|
||||||
hex=$("$cmd" --json users show "$npub" 2>/dev/null | jq -r '.pubkey // .public_key // .hex // empty' 2>/dev/null || true)
|
hex=$(npub_to_hex "$npub")
|
||||||
[[ -z "$hex" ]] && hex="$npub"
|
|
||||||
if [[ "$who" == "B" ]]; then B_NPUB="$npub"; B_HEX="$hex"
|
if [[ "$who" == "B" ]]; then B_NPUB="$npub"; B_HEX="$hex"
|
||||||
else C_NPUB="$npub"; C_HEX="$hex"; fi
|
else C_NPUB="$npub"; C_HEX="$hex"; fi
|
||||||
save_state "${who}_NPUB" "$npub"
|
save_state "${who}_NPUB" "$npub"
|
||||||
save_state "${who}_HEX" "$hex"
|
save_state "${who}_HEX" "$hex"
|
||||||
info "$who npub: $npub"
|
info "$who npub: $npub"
|
||||||
|
[[ "$hex" != "$npub" ]] && info "$who hex: $hex"
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt_for_a_npub() {
|
prompt_for_a_npub() {
|
||||||
@@ -174,11 +193,10 @@ prompt_for_a_npub() {
|
|||||||
read -r A_NPUB
|
read -r A_NPUB
|
||||||
save_state "A_NPUB" "$A_NPUB"
|
save_state "A_NPUB" "$A_NPUB"
|
||||||
fi
|
fi
|
||||||
A_HEX=$(wn_b --json users show "$A_NPUB" 2>/dev/null \
|
A_HEX=$(npub_to_hex "$A_NPUB")
|
||||||
| jq -r '.pubkey // .public_key // .hex // empty' 2>/dev/null || true)
|
|
||||||
[[ -z "$A_HEX" ]] && A_HEX="$A_NPUB"
|
|
||||||
save_state "A_HEX" "$A_HEX"
|
save_state "A_HEX" "$A_HEX"
|
||||||
info "A hex: $A_HEX"
|
info "A npub: $A_NPUB"
|
||||||
|
[[ "$A_HEX" != "$A_NPUB" ]] && info "A hex: $A_HEX"
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- relays ------------------------------------------------------------------
|
# --- relays ------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user