Skip to content

Docs: every Sphere.init sample in 4 of 5 consumer docs is broken (network is required), plus ~30 other false claims #773

Description

@MastaP

Found by an audit of README.md, all of docs/, and CLAUDE.md against the code on fix/766-sphere-lifecycle. Severity-graded: WRONG = a consumer following it fails; STALE = describes an older shape; INCOMPLETE = correct but missing something new.

Headline: the primary onboarding path does not work as documented

Sphere.init calls resolvePaymentsV2Composition(options.walletApi, options.network) before anything else (core/Sphere.ts:651). network is required, and it is compared to walletApi.network as an exact string. Proven by execution:

resolvePaymentsV2Composition({network:'testnet2',baseUrl:'…'}, undefined)
  → INVALID_CONFIG: walletApi.network "testnet2" does not match the Sphere network "undefined"
resolvePaymentsV2Composition({network:'testnet2',baseUrl:'…'}, 'testnet')
  → INVALID_CONFIG: … does not match the Sphere network "testnet"

The docs' pervasive pattern — createBrowserProviders({ network: 'testnet' }) paired with walletApi: { network: 'testnet2' } — fails even after adding network, because all three must be the same literal. And createBrowserProviders/createNodeProviders do not return network in the bundle (impl/browser/index.ts:198-220), so {...providers} cannot supply it.

Affected: README.md (13 samples: :73, 238, 388, 395, 565, 579, 909, 1116, 1147, 1164, 1174, 1198, 1243), docs/INTEGRATION.md (8: :210, 252, 322, 440, 931, 996, 1030, 1171), docs/QUICKSTART-BROWSER.md (all 8 framework samples), docs/API.md (:22, 808, 840 — the init option block does not list network at all).

docs/QUICKSTART-NODEJS.md is the only consumer doc that gets this right, and CLAUDE.md:122-129 states the rule correctly — so the repo contradicts itself.

WRONG — selected; a consumer following any of these fails

File:line Says Code
README.md:334-337, 342, 1206 sphere.on('identity:changed', e => e.data.addressIndex) Handlers receive the payload directly; no .data wrapper (Sphere.ts:4155). Every event.data.* read is undefined
README.md:1049-1064 sphere.on('transport:relay_added' | 'relay_removed' | 'error') Not in SphereEventType — TS error, never fires. These are on the transport provider's own bus
README.md:300, 1230-1231; INTEGRATION.md:962 getNametagForAddress(1) Takes an addressId string, not an index (Sphere.ts:2114). A number returns undefined
README.md:1246 const { sphere } = await Sphere.load({…}) load returns Promise<Sphere>sphere is undefined
README.md:687 importFromJSON without walletApi Fail-closed; returns {success:false, error:'Sphere requires a wallet-api composition…'}
README.md:944 relays: ['wss://relay.unicity.network'] Dropped in #765; the v1 relay is NXDOMAIN
README.md:610-611 "Without config the transport defaults to mainnet relays" Defaults to damus/nos.lol/nostr.band. NETWORKS.mainnet.nostrRelays is the testnet relay
README.md:461, 464; API.md:530 sendMessage(id, txt, {replyToId}), fetchMessages(id, {limit}) Third params are replyToId?: string and since?: number — the objects land in the wrong slot
INTEGRATION.md:944-947; NAMETAG-BINDINGS.md:30-38, 164-169 Registration mints a self-issued UnicityIdToken ensureUnicityIdTokenStored/createUnicityIdMinter have zero hits — removed at the 2.0.0 bump. Contradicts README:1110 and API.md:755
INTEGRATION.md:580; API.md:314 Receive dedup "by genesis-stable tokenId via a durable seen-set" Dedup is by (tokenId, stateHash) (Receive.ts:75-77); there is no seen-set. Pinned by history.test.ts:217
INTEGRATION.md:1285 generateMnemonic(12) Signature is (strength: 128 | 256) — type error, and bip39 throws
API.md:82 identity is FullIdentity | null Returns Identity | nullno privateKey
CONNECT.md:648 and CLAUDE.md:235 sphere_subscribe refuses the 4 wallet events The host answers SUCCESS deliberately (ConnectHost.ts:1112-1114), commented that throwing "silently broke every dApp built before 2.1". A host implementer following this breaks pre-2.1 dApps
CONNECT.md:123, 146-149 PostMessageTransport.forHost() no-args; WebSocketTransport.forClient/forHost forHost(target, options) needs two args; the WS methods do not exist (createServer/createClient)
PAYMENTS-V2-DESIGN.md:216-219 Layout lists payments-v2/session/, transfer/ Neither exists
LEGACY-INVENTORY.md:214, 257, 323 DEFAULT_AGGREGATOR_URL/DEV_AGGREGATOR_URL, a 'dev' trust-base case, RegistryNetwork with 'dev' All removed by #765

INCOMPLETE — highest consequence first

  1. docs/CONNECT.md:393, 403, 503, 837, 849, 885 — six autoConnect/ConnectClient samples omit network. The gate does treat a missing network as a mismatch (compatibility.ts:71-76 → 4008), but these are option-focused fragments and the doc establishes network as required at :62, :65, :368, :451. Incomplete rather than wrong.

  2. docs/INTEGRATION.md:818 publishes the StorageProvider interface with saveTrackedAddresses and no contract. The port now requires read-merge-write, union by index, greater updatedAt wins hidden, serialized per backing store (storage/storage-provider.ts:73-105). A custom provider written from this doc clobbers addresses — the exact Remove the process-global state: one Sphere per network, disposable, and concurrent instances must not interfere #766 data-loss bug.

  3. docs/API.md:640TrackedAddressEntry.index needs the uint32 rule; non-conforming rows are dropped on read.

  4. docs/API.md:20-44 — init options omit network (required), verification, groupChat, market, communications, discoverAddresses, debug, onProgress.

  5. Sphere.clear()/import() now destroy live Spheres on the same backing store — no reference doc says so.

Genuinely absent

Two stale SOURCE comments (same defect class)

  • connect/types.ts:169intentDeadlineMs documented as "Default: 90000"; actual DEFAULT_INTENT_DEADLINE_MS = 180000 (ConnectHost.ts:94). The 4200 in that same comment is correct (INTENT_CANCELLED, protocol.ts:95)
  • tests/unit/connect/protocol-surface.test.ts:31 — repeats the dead METHOD_NOT_FOUND claim (connect/protocol.ts:75 is its only non-test reference; the real answer is PERMISSION_DENIED 4002)

Clean

No doc calls a removed export (scripts/check-removed-refs.mjs confirms). No doc passes network:'dev', accounting, swap or paymentsV2. The #765 network story is accurate everywhere. Connect counts (14/6/13, protocol 2.1, 4 wallet events, 4-of-14 while locked) all match source.

Suggested order

  1. The missing network in every init sample — it breaks the primary onboarding path.
  2. INTEGRATION.md's StorageProvider contract — silent data loss for custom providers.
  3. The wrong signatures and the .data wrapper — each fails at runtime for a copying consumer.
  4. The UnicityIdToken claim in two docs — describes a feature deleted two majors ago.
  5. Everything else.

Audited 2026-09-03 against fix/766-sphere-lifecycle. Line numbers were accurate then; verify before editing.


Correction (2026-09-03, after re-verification)

Two entries in the original filing were wrong and have been fixed above. Recording the change rather than editing silently:

  • connect/types.ts was misreported. The original said the comment's error code was wrong (42004201) and the default was 120000. Both were mistaken: 4200 is correct (INTENT_CANCELLED), 4201 is a different code (INTENT_OUTCOME_UNKNOWN, protocol.ts:109), and 120000 is DEFAULT_HANDSHAKE_DEADLINE_MS — a different field entirely. The genuine defect is only that the documented default 90000 should be 180000.
  • The six Connect client samples were over-graded as WRONG; they are INCOMPLETE, and moved accordingly.
  • docs/CONNECT.md:875 await hasExtension() was dropped entirelyhasExtension(): boolean exists and awaiting a boolean is valid. Redundant, not broken.

Everything else in this issue was verified directly against source and stands, including the network-missing headline, which was proven by executing resolvePaymentsV2Composition.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions