Skip to content

init --nametag: identity block misses just-minted nametag (cli-wallet-lifecycle flake) #42

Description

@vrogojin

Carry-over from #40 item #2 PR (#41). The integration test
test/integration/cli-wallet-lifecycle.integration.test.ts

`sphere init --nametag ` mints the nametag during wallet creation

intermittently fails against public testnet. The PR landed the
canonical-UX regex fix (matches `nametag : @`) but the
underlying race + transient-timeout shape remains.

This is the "right" fix split out of #40 so it can be tracked
separately.

Repro

```bash

from sphere-cli working copy

npm run build
SPHERE_ALLOW_MNEMONIC_NON_TTY=1 \
npx vitest run --config vitest.integration.config.ts \
test/integration/cli-wallet-lifecycle.integration.test.ts
```

Failing assertion (when it fails):

```
expected 'Initializing wallet on testnet...\n...' to match
/nametag\s*:\s*@it_/


with the actual identity block printing \`nametag : (none)\`. The
companion test in the same file —

> \`sphere nametag my\` reports the registered nametag after init --nametag

— **passes consistently**, which proves the mint actually went
through; only the in-process render missed it.

## Three failure modes

1. **In-process state propagation gap (the load-bearing one).**
   \`Sphere.init({ nametag })\` mints on-chain, but the identity
   object the CLI prints in \`src/legacy/legacy-cli.ts\` (\`case 'init':\`,
   ~line 1640) is read before the post-mint identity refresh
   propagates. So the mint succeeded but \`identity.nametag\` is
   still \`undefined\` when \`renderIdentity()\` runs.

2. **Aggregator latency.** \`goggregator-test.unicity.network\` is
   shared infra; the submit → poll → inclusion-proof round-trip
   can spike past the test's 240s budget under load. Real network
   tail, not really a flake.

3. **Nostr publish in-band with the mint.** \`Sphere.init({ nametag })\`
   also publishes the nametag-binding event to
   \`nostr-relay.testnet.unicity.network\` so peers can resolve
   \`@<name>\` later. If the publish stalls, the whole init await
   stalls. The Nostr binding doesn't have to be in-band — peers
   re-resolve lazily and the binding is republished when the
   wallet next opens.

## Proposed fix

### sphere-cli — make the identity block reflect post-mint state

In \`legacy-cli.ts\` \`case 'init':\` (~1640), after the
\`Sphere.init({ nametag })\` await completes, **re-read identity from
\`sphere.identity\`** instead of using whatever was captured before
the mint. Today the print sequence and the mint sequence race; the
fix is to make the print depend on the mint.

If the SDK doesn't expose a \"identity is now fresh\" signal, fall
back to re-fetching after a single yield (\`await Promise.resolve()\`)
— ugly but bounded.

### sphere-sdk — make Nostr publish out-of-band (best-effort)

\`Sphere.init({ nametag })\` should:
- complete the on-chain mint (in-band — this IS the operation the
  user asked for)
- fire-and-forget the Nostr binding publish (out-of-band, retried
  by the transport layer's existing republish hooks)

Today both run in-band. Splitting them means a Nostr relay outage
doesn't fail \`init --nametag\` — the on-chain token is what matters
for ownership; the Nostr binding is a discoverability cache.

Probably one-line change in \`NametagMinter\` / \`registerNametag\`
to drop \`await\` on the publish.

### Test budget

Once the fix lands, the 240s timeout in the test should be
reduced (current value was generous specifically to absorb the
Nostr publish stall). 180s is reasonable.

## Acceptance criteria

- [ ] Identity block printed by \`sphere init --nametag <name>\`
  contains \`nametag : @<name>\` synchronously after the mint
  completes — no \`(none)\` race.
- [ ] \`sphere init --nametag\` does NOT block on Nostr publish
  success. A stalled relay should still let init succeed (mint
  is what counts).
- [ ] Test budget in
  \`cli-wallet-lifecycle.integration.test.ts\` cut to 180s; test
  reliably green over 5 consecutive runs.
- [ ] Companion test (\`nametag my reports\`) continues to pass
  (the on-chain mint and local persistence are unchanged).

## Out of scope

- Multi-target / multi-asset selector flags (issue #40 item #3,
  separately deferred).
- NFT-only \`invoice pay\` flow (issue #40 item #4, separately
  deferred).

## Related

- sphere-cli #40 — parent followup bundle
- sphere-cli #41 — the regex-scrub PR that this carries forward
  from (#41 made the test correctly identify the mint failure;
  this issue fixes the underlying race)
- CLAUDE.md \"When nametag token is minted on-chain\" — references
  the four entry points (\`Sphere.init({ nametag })\`,
  \`sphere.registerNametag()\`, \`cli init --nametag\`, \`cli nametag\`).
  Fix should cover all of them, not just the cli case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions