Skip to content

feat: top-level init + pointer namespace + non-TTY mnemonic opt-in#10

Merged
vrogojin merged 1 commit intomainfrom
feat/pointer-namespace-and-top-level-init
May 7, 2026
Merged

feat: top-level init + pointer namespace + non-TTY mnemonic opt-in#10
vrogojin merged 1 commit intomainfrom
feat/pointer-namespace-and-top-level-init

Conversation

@vrogojin
Copy link
Copy Markdown
Contributor

@vrogojin vrogojin commented May 7, 2026

Summary

Restores three CLI surfaces the sphere-sdk e2e shell suites need but
the @unicity-sphere/cli extraction dropped:

  • Top-level init/status/clear — legacy bridges added back so
    scripts driving sphere init --profile --network testnet,
    sphere status, sphere clear keep working. The wallet init
    bridge stays — these are aliases.
  • Native sphere pointer namespacestatus / flush / recover
    for the aggregator-pointer layer. Implemented directly against
    ProfilePointerLayer methods on the SDK.
  • SPHERE_ALLOW_MNEMONIC_NON_TTY=1 — opt-in for the legacy init
    command to emit the mnemonic on a non-TTY stdout, so e2e harnesses
    that need to chain init→recover-from-mnemonic across scripts can
    capture it.

Verified end-to-end against sphere-sdk/tests/e2e/pointer-N1.sh on a
local Docker Nostr relay + js-faucet stack — PASS: pointer-N1 with
5/5 assertions.

Compatibility

pointer-commands.ts runtime-imports
@unicitylabs/sphere-sdk/profile/node via dynamic import(). When the
installed SDK predates the Profile-module release, pointer status
/ flush / recover exit with code 2 and a precise diagnostic
("installed sphere-sdk does not export profile/node — upgrade to a
version that ships the Profile/aggregator-pointer module"). The CLI
typechecks against the older SDK; pointer commands start working
automatically as soon as the SDK upgrade lands.

init / status / clear are pure legacy bridges and start working
on day one against any SDK that has those legacy commands (i.e. every
SDK predating the legacy strip-out).

New dependency

multiformats@^14 — used for the CID decode in pointer recover.
The SDK already pulls this in transitively; listing it explicitly in
the CLI keeps the build hermetic against a future SDK that drops the
transitive.

Test plan

  • npm run typecheck clean against released SDK (no profile module).
  • npm run typecheck clean against pointer-aware SDK
    (uxf branch with profile/node export).
  • npm run build clean.
  • sphere init --help, sphere pointer --help,
    sphere pointer status/flush/recover --help all show
    command-specific Usage lines (the e2e
    cli_supports_command probe matches them).
  • sphere-sdk pointer-N1 end-to-end against local Docker relay
    + faucet — PASS (5/5 assertions, 14s wall-clock).

Related

sphere-sdk's tests/e2e/lib/resolve-cli.sh already searches the
worktree paths (sphere-cli-work/sphere-cli/bin/sphere.mjs) and
probes <cli> <subcommand> --help for the commands this PR adds —
no further coordination needed on that side.

Restores three CLI surfaces the e2e shell suites need:

(1) Top-level `sphere init` / `sphere status` / `sphere clear`
    Pre-extraction, the in-tree sphere-sdk CLI exposed `init`,
    `status`, `clear` as bare top-level commands. Phase 1 of the
    extraction landed `wallet init` / `wallet status` / `wallet
    clear` (legacy bridges) but dropped the unprefixed top-level
    aliases, breaking every shell test that drove `sphere init
    --profile --network testnet`. Re-adds them as legacy bridges
    that map back to the same legacy switch/case so wire shape is
    unchanged.

(2) Native `sphere pointer` namespace
    The aggregator-pointer layer is implemented in sphere-sdk's
    profile module (since the pointer-layer release). The in-tree
    CLI never exposed it; tests have driven `sphere pointer
    flush / status / recover` against a TODO surface that now
    lands. Three subcommands:

      sphere pointer status    Reachable / Blocked / Probe FP
                                + latest valid version
      sphere pointer flush     payments.sync() round-trip
                                (save → CAR pin → bundle ref →
                                pointer publish)
      sphere pointer recover   recoverLatest() — prints either
                                "Recovered v=N cid=…" or "No
                                pointer anchor published yet"

    Native (not a legacy bridge) — implemented directly against
    the SDK's ProfilePointerLayer methods.

    SDK compatibility: the profile module ships in sphere-sdk
    versions that include the pointer-layer work. To let this CLI
    merge against older SDK releases, `pointer/sphere-init.ts`
    runtime-imports `@unicitylabs/sphere-sdk/profile/node` via
    dynamic `import()`. When the SDK predates that subpath,
    pointer commands exit with code 2 and a precise diagnostic
    ("installed sphere-sdk does not export profile/node — upgrade
    to a version that ships the Profile/aggregator-pointer
    module"). The CLI typechecks against the older SDK; pointer
    commands start working as soon as the SDK upgrade lands —
    no second CLI release required.

    New runtime dep: `multiformats` (^14) for the CID
    decode in `pointer recover`. The SDK already pulls this in;
    listing it explicitly in the CLI keeps the build hermetic if
    a future SDK version drops the transitive.

(3) Non-TTY mnemonic emission opt-in
    Legacy `init` suppresses the 24/12-word mnemonic on a
    non-TTY stdout (security: prevents accidental persistence in
    logs / CI). E2E harnesses that need to chain
    init→recover-from-mnemonic across scripts blocked on this.
    Adds `SPHERE_ALLOW_MNEMONIC_NON_TTY=1` opt-in: when set, emit
    the mnemonic to stdout as a single line (so harness greps
    match cleanly) plus a stderr note. Verbose name by design —
    this is a footgun for production users and tests opt in
    explicitly.

End-to-end verified against sphere-sdk's tests/e2e/pointer-N1.sh
on a local Docker relay + faucet stack:

  PASS: pointer-N1 (5/5 assertions)
    ✓ init creates Profile-mode wallet, mnemonic captured
    ✓ pointer flush succeeds (publishes anchor)
    ✓ pointer status: reachable=yes
    ✓ pointer status: blocked=no
    ✓ pointer status: probe fingerprint present
@vrogojin vrogojin merged commit 16848ec into main May 7, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant