Skip to content

Migrate from deprecated IpfsStorageProvider to createNodeProfileProviders (Profile + aggregator pointer + IPFS CAR) #23

@vrogojin

Description

@vrogojin

Summary

The CLI bootstraps wallets with createNodeProviders and then explicitly attaches the deprecated IpfsStorageProvider (src/legacy/legacy-cli.ts:282-285):

// Attach IPFS storage provider for sync if available
if (providers.ipfsTokenStorage) {
  await sphereInstance.addTokenStorageProvider(providers.ipfsTokenStorage);
}

The IpfsStorageProvider implements the IPNS-based mutable-pointer flow, which the sphere-sdk has deprecated in favor of the Profile token-storage path (OrbitDB + aggregator pointer + IPFS CAR). The deprecation warning is currently spamming every CLI invocation:

[sphere-sdk] IpfsStorageProvider is DEPRECATED. The IPNS-based mutable-pointer flow it implements
is superseded by the Profile token-storage path (OrbitDB + aggregator pointer + IPFS CAR).
Migrate via createNodeProfileProviders / createBrowserProfileProviders. ...

Real-world impact

Beyond log spam, IPNS-based sync uses last-writer-wins semantics. In a multi-device setup (peer1-alice + peer2-alice sharing a mnemonic) both devices race to publish their IPNS pointer, and a later write from one device can clobber state from the other before it's been merged. This came up while validating #223 — multi-device state propagation is unreliable on the current IPNS path. The Profile path (OrbitDB) uses CRDT replication and avoids the data-loss window.

Migration target

sphere-sdk exports createNodeProfileProviders:

import { createNodeProfileProviders } from '@unicitylabs/sphere-sdk/profile/node';

But it returns ONLY { storage, tokenStorage }. The CLI also needs oracle, transport, market, groupChat, etc. from createNodeProviders. The migration is therefore a combined factory call:

// PROPOSED — current CLI bootstrap at src/legacy/legacy-cli.ts:252-287
const baseProviders = createNodeProviders({
  network: config.network,
  dataDir: config.dataDir,
  tokensDir: config.tokensDir,
  // Drop tokenSync.ipfs — Profile replaces IPNS
  market: true,
  groupChat: true,
});
const profileProviders = createNodeProfileProviders({
  network: config.network,
  dataDir: config.dataDir,
  // profileConfig.orbitDb.directory defaults to `${dataDir}/orbitdb`
});

const providers = {
  ...baseProviders,
  storage: profileProviders.storage,
  tokenStorage: profileProviders.tokenStorage,
};

// Drop the post-init `addTokenStorageProvider(ipfsTokenStorage)` call entirely.

Scope estimate

Multi-day refactor. Touches:

  1. src/legacy/legacy-cli.ts getSphere() — provider construction
  2. Wallet init paths (sphere init, sphere init --mnemonic, sphere wallet create)
  3. File-storage layout under ~/.sphere-cli-<wallet>/ — Profile adds orbitdb/ subdirectory
  4. Existing CLI wallets in the wild — migration code to detect "this profile was created with IpfsStorageProvider" and either migrate or co-exist
  5. CI / test infrastructure references to the IPFS storage path
  6. The two existing call sites — line 256 (getSphere) and line 1806 — and any tests that mock them

Risks

  • Backwards compatibility: existing CLI wallets have token state in the IPNS-pointer format. A naive switch breaks them. Need a one-time read-IPNS-write-Profile migration path, or co-existence with a soft cutover.
  • OrbitDB peer connectivity: Profile relies on libp2p peers. Need to validate the network config defaults (profileOrbitDbPeers) are reachable from CLI environments.
  • L1 vesting cache and any other side-channel storage that assumed file-storage layout.

Related

  • sphere-sdk #223 (cross-process Nostr delivery) — comment 4525528875 enumerates this as item 2 of four §C.4/§D follow-ups
  • PR sphere-sdk#229 corrected the manual-test script for #223 — surfaces this CLI-side gap on the §D.4 wipe-and-recover path

Acceptance

  • CLI bootstraps via createNodeProfileProviders for storage + tokenStorage
  • IpfsStorageProvider deprecation warning gone from CLI output
  • Existing CLI wallets migrate cleanly (or doc'd workaround)
  • manual-test-full-recovery.sh §D.4 (wipe + recover from mnemonics with --no-nostr, IPFS-only) succeeds
  • sphere-sdk #230 (invoiceTermsCache stale) and sphere-cli #N (ensureSync 'nostr'→'full') are independent — this migration shouldn't depend on them

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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