@le-space/orbitdb-storage-bridge 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Mathias Buus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,290 @@
1
+ # OrbitDB Storage Bridge
2
+
3
+ > **OrbitDB database backup, restoration and replication through pluggable storage backends, with hash and identity preservation**
4
+
5
+
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Node.js](https://img.shields.io/badge/Node.js-22+-green.svg)](https://nodejs.org/)
8
+ [![CI/CD Pipeline](https://github.com/NiKrause/@le-space/orbitdb-storage-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/NiKrause/@le-space/orbitdb-storage-bridge/actions/workflows/ci.yml)
9
+ [![ESLint](https://img.shields.io/badge/ESLint-passing-brightgreen.svg)](https://github.com/NiKrause/@le-space/orbitdb-storage-bridge/actions/workflows/ci.yml)
10
+ [![npm version](https://img.shields.io/npm/v/@le-space/orbitdb-storage-bridge.svg)](https://www.npmjs.com/package/@le-space/orbitdb-storage-bridge)
11
+
12
+ > [!NOTE]
13
+ > **Renamed from `orbitdb-storacha-bridge`.** Up to 0.6.0 this package was published as
14
+ > `orbitdb-storacha-bridge`. From 0.7.0 it is `@le-space/orbitdb-storage-bridge`, because Storacha is no
15
+ > longer the only backend it bridges to. The rename changes no API — swap the dependency and the
16
+ > import specifiers:
17
+ >
18
+ > ```bash
19
+ > npm uninstall orbitdb-storacha-bridge
20
+ > npm install @le-space/orbitdb-storage-bridge
21
+ > ```
22
+ >
23
+ > `orbitdb-storacha-bridge/courier-sync` becomes `@le-space/orbitdb-storage-bridge/courier-sync`, and so on
24
+ > for every entry point. Names that refer to Storacha itself stay as they are:
25
+ > `OrbitDBStorachaBridge`, `StorachaIntegration.svelte`, `backends/storacha`, the `storacha_*`
26
+ > localStorage keys that hold saved logins — and so does the debug namespace
27
+ > `libp2p:orbitdb-storacha:*`.
28
+
29
+
30
+ > [!IMPORTANT]
31
+ > **The Storacha upload service is gone.** Writes were switched off in May 2026 and the
32
+ > service has since been decommissioned. Backup no longer works, and restore only reaches
33
+ > blocks that something other than Storacha still holds. See
34
+ > [Status: Storacha sunset](#status-storacha-sunset-may-2026) and
35
+ > [docs/STORAGE-BACKENDS.md](docs/STORAGE-BACKENDS.md) for where to go instead.
36
+
37
+
38
+ ## Table of Contents
39
+
40
+ - [OrbitDB Storage Bridge](#@le-space/orbitdb-storage-bridge)
41
+ - [Table of Contents](#table-of-contents)
42
+ - [Status: Storacha sunset (May 2026)](#status-storacha-sunset-may-2026)
43
+ - [What we want to accomplish](#what-we-want-to-accomplish)
44
+ - [The Challenge of Distributed Data Persistence](#the-challenge-of-distributed-data-persistence)
45
+ - [Architectural Considerations for Local-First Applications](#architectural-considerations-for-local-first-applications)
46
+ - [Use Cases](#use-cases)
47
+ - [Architecture Notes](#architecture-notes)
48
+ - [What This Does](#what-this-does)
49
+ - [Roadmap](#roadmap)
50
+ - [Installation](#installation)
51
+ - [Environment Setup](#environment-setup)
52
+ - [Demo](#demo)
53
+ - [NodeJS Demo Scripts (full backup with Manifest, Identity and AccessController and entries blocks)](#nodejs-demo-scripts-full-backup-with-manifest-identity-and-accesscontroller-and-entries-blocks)
54
+ - [Svelte Components](#svelte-components)
55
+ - [How It Works](#how-it-works)
56
+ - [Restore Mechanism](#restore-mechanism)
57
+ - [Logging](#logging)
58
+ - [Testing](#testing)
59
+ - [Contributing](#contributing)
60
+ - [License](#license)
61
+
62
+
63
+ ## Status: Storacha sunset (May 2026)
64
+
65
+ Storacha switched off user writes in **May 2026** and has since decommissioned the service.
66
+ Verified on 2026-09-05:
67
+
68
+ | Check | Result |
69
+ | --- | --- |
70
+ | `up.storacha.network`, `console.storacha.network`, `indexer.storacha.network`, `forge.storacha.network` | no DNS record — upload, console and indexing endpoints are gone |
71
+ | `storacha.network`, `docs.storacha.network` | `301` → `fil.one`, the team's new S3-compatible product |
72
+ | `storacha.link`, `w3s.link` | `301` → `dweb.link`; the gateways only forward to the public IPFS gateway now |
73
+ | the widget demo CID linked in the roadmap below | `504` on `w3s.link`, `dweb.link`, `ipfs.io` and `trustless-gateway.link` |
74
+ | `@storacha/client` on npm | last release `2.1.4`, 2026-05-15, not marked deprecated |
75
+
76
+ The shutdown is traceable in the open:
77
+ [`upload-service#708`](https://github.com/storacha/upload-service/pull/708) added a `writesDisabled`
78
+ kill switch that makes the eight user-initiated write capabilities
79
+ (`space/blob/{add,remove,replicate}`, `space/index/add`, `upload/{add,remove}`, `store/{add,remove}`)
80
+ return `ServiceUnavailable`, and [`w3infra#636`](https://github.com/storacha/w3infra/pull/636) wired
81
+ `WRITES_DISABLED=true` into the production stack — both merged 2026-05-15. Five days later Storacha
82
+ shipped `storacha space migrate`
83
+ ([`@storacha/filecoin-pin-migration`](https://www.npmjs.com/package/@storacha/filecoin-pin-migration)),
84
+ a migration path from Storacha spaces to Filecoin Onchain Cloud. That tool reads spaces through
85
+ endpoints that no longer resolve, so the official migration window has closed.
86
+
87
+ We found no announcement page: the Storacha blog now redirects to `fil.one/blog`, which carries a
88
+ single post ("Introducing Fil One", 2026-08-12). The dates above come from the code and the DNS,
89
+ not from a press release.
90
+
91
+ **What this means for this library**
92
+
93
+ - **Backup does not work.** Every write path ends in `client.uploadFile()` against `up.storacha.network`.
94
+ - **Restore only reaches what someone else still holds.** The p2p-first path still finds blocks that a
95
+ peer or another pinning service pins; the gateway fallback and the `capability.upload.list`
96
+ discovery step cannot reach Storacha any more.
97
+ - **The OrbitDB half is unaffected.** Block extraction, CID bridging, CAR packing, identity
98
+ preservation, UCAN signing and courier-sync are backend-agnostic — only the handful of Storacha
99
+ client methods mapped in [docs/STORAGE-BACKENDS.md](docs/STORAGE-BACKENDS.md) need a new home.
100
+
101
+ If you still have an OrbitDB instance with the blocks in it, re-pin them somewhere else now: the data
102
+ is only as alive as the peers that hold it.
103
+
104
+
105
+ ## What we want to accomplish
106
+
107
+ ### The Challenge of Distributed Data Persistence
108
+
109
+ In local-first, peer-to-peer applications built on OrbitDB, data naturally replicates across participating peers through libp2p network connections. Under ideal conditions, this distributed architecture provides inherent redundancy—if one peer loses data, they can resynchronize from other active peers in the network. This peer-to-peer replication model represents the current state of OrbitDB technology.
110
+
111
+ While relay nodes and pinning services (running Helia and OrbitDB instances) can provide additional decentralized persistence for database entries and IPFS-referenced content, the ecosystem still lacks comprehensive infrastructure for long-term archival of large-scale OrbitDB deployments.
112
+
113
+ ### Architectural Considerations for Local-First Applications
114
+
115
+ OrbitDB's data model differs fundamentally from traditional centralized databases. In local-first architectures, users typically host their own data locally and selectively replicate with specific peers based on collaboration requirements—not with the entire network. This selective replication is essential for scalability and user experience.
116
+
117
+ However, as OrbitDB instances grow (consider a blog database accumulating years of posts), replication times increase proportionally. At scale, databases require archival strategies and potential sharding to maintain performant synchronization and optimal user experience.
118
+
119
+ ### Use Cases
120
+
121
+ This bridge addresses several critical scenarios:
122
+
123
+ **1. Long-term Archival**
124
+ Archive large OrbitDB instances to Storacha/Filecoin storage, enabling efficient cold storage for historical data while maintaining fast replication of active datasets.
125
+
126
+ **2. Disaster Recovery**
127
+ Provides recovery options when all active peers lose data simultaneously. Users can restore databases from Storacha using either their original identity or a new identity, ensuring business continuity beyond the peer-to-peer network's availability.
128
+
129
+ **3. Network Resilience**
130
+ Historically, various network environments (corporate networks, ISPs, regional restrictions) have blocked critical protocols including WebRTC and WebSocket/WebTransport. While libp2p's multi-transport architecture provides numerous fallback options, having an additional restoration pathway through IPFS/Storacha offers defense-in-depth for network-hostile environments. Users can restore databases directly from IPFS and maintain incremental backups after each database mutation.
131
+
132
+ **4. Access Control & Delegation**
133
+ The bridge supports UCAN (User Controlled Authorization Networks) authentication with planned delegation capabilities between OrbitDB instances. This enables fine-grained, time-bound access control for Storacha backup spaces, allowing users to securely share access with collaborators or recovery agents.
134
+
135
+ ### Architecture Notes
136
+
137
+ Currently, Storacha backup and restore operations utilize Storacha's gateway infrastructure to interface with Filecoin's decentralized storage network. This hybrid approach balances accessibility with decentralization during the current phase of the Filecoin ecosystem's evolution.
138
+
139
+ That description is now historical: the gateway infrastructure it relies on was decommissioned in 2026 (see [Status: Storacha sunset](#status-storacha-sunset-may-2026)). The hybrid shape of the design still holds — a backend that stores bytes, an IPFS network that serves them — but the backend slot is open. [docs/STORAGE-BACKENDS.md](docs/STORAGE-BACKENDS.md) compares the candidates.
140
+
141
+ ## What This Does
142
+
143
+ Backup and restore between **OrbitDB databases** and **Storacha/Filecoin** with full hash and identity preservation. Works in both Node.js and browser environments.
144
+
145
+ The project includes **Svelte components** for browser-based demos and integration (see [SVELTE-COMPONENTS.md](SVELTE-COMPONENTS.md) for detailed documentation).
146
+
147
+ **Features:**
148
+
149
+ - backup/restore between OrbitDB and Storacha in browsers and NodeJS via Storacha key and proof credential
150
+ - full backup per space
151
+ - timestamped backups (multiple backups per space - restore last backup by default)
152
+ - Storacha Svelte components for integration into Svelte projects
153
+ - UCAN authentication
154
+ - Backup/restore functionality with hash and identity preservation
155
+ - OrbitDB CAR file storage [OrbitDB CustomStorage](https://github.com/orbitdb/orbitdb/blob/main/docs/STORAGE.md)
156
+
157
+ ## Roadmap
158
+
159
+ > Being re-based on a backend interface instead of a single vendor — the plan is
160
+ > [issue 54](https://github.com/NiKrause/@le-space/orbitdb-storage-bridge/issues/54), not here. The WebAuthn/varsig items below survive
161
+ > unchanged; the Storacha-named ones become backend-agnostic.
162
+
163
+ - [ ] Live parallel persistence: hand an open database a backend-backed OrbitDB `ComposedStorage`, so every block is written to a backend **as it is created** — during sync and after each update — rather than only when a backup runs.
164
+ - [ ] Today a block becomes durable somewhere else only if bitswap reaches a peer that keeps it, gossipsub reaches a subscriber, or somebody runs a backup. All three depend on another party being reachable at that moment; a write-through storage does not.
165
+ - [ ] The seam already exists: [`lib/car-storage.js`](lib/car-storage.js) implements OrbitDB's storage shape (`put`/`get`/`del`/`iterator`/`merge`) against a CAR file, and `ComposedStorage` is designed to fan a write out to more than one place. This points the same seam at a network backend instead.
166
+ - [ ] Aleph Cloud is the first candidate, because it is the only evaluated backend a browser can write to with no key at all — `POST /api/v0/add` answers unauthenticated with an open CORS header. See [docs/STORAGE-BACKENDS.md](docs/STORAGE-BACKENDS.md); persistence there needs the wallet-signed STORE message, not the ingest alone.
167
+ - [ ] Open question worth settling first: what a write-through storage does when the backend is unreachable. Blocking a local write on a network round trip would make the database only as available as the backend, which is the opposite of the point — so it queues, and the queue is the design.
168
+
169
+ - [ ] v0.4.4 (Feb 2026): Latest-backup pointer (single CID) to avoid listing via the Storacha SDK and restore from the IPFS network for initial OrbitDB syncs.
170
+ - [ ] After each backup, write a small pointer record (JSON) that stores the latest metadata CID, CAR CID, and last heads (block CID).
171
+ - [ ] Store that pointer in a user-controlled place (local storage, QR/share link, WebAuthN largetBlog extension or file download).
172
+ - [ ] v0.5.0 (Feb 2026): OrbitDB CustomStorage (StorachaStorage) ([issue 23](https://github.com/NiKrause/@le-space/orbitdb-storage-bridge/issues/23)).
173
+ - [ ] v0.6.0 (Mar 2026): WebAuthN + varsig signing/verification (Ed25519 and P-256) for OrbitDB oplog. https://github.com/ChainAgnostic/varsig/blob/main/README.md
174
+ - [ ] v0.6.1 (Mar 2026): WebAuthN + SimpleEncryption example that uses WebAuthN+PRF key material for encrypted backups and restore.
175
+ - [ ] v0.7.0 (Apr 2026): WebAuthN + OrbitDB AccessController (store a UCAN instead of only a DID for admin/write access).
176
+ - [ ] Alice (authenticated via UCAN or Storacha credentials) can delegate/revoke access for Bob with custom/default capabilities ([issue 16](https://github.com/NiKrause/@le-space/orbitdb-storage-bridge/issues/16)). See [WebAuthN Upload Wall](https://github.com/NiKrause/ucan-upload-wall/tree/browser-only/web) and the [live demo](https://bafybeibdcnp7pr26okzr6kbygcounsz3klyg3vydxwwovmz2ljyzfmprre.ipfs.w3s.link/).
177
+ - [ ] v0.7.1 (May 2026): Storacha Backup & Restore Svelte widget with WebAuthN-varsig UCAN signing/verification (Ed25519/P-256).
178
+ - [ ] v0.7.2 (May 2026): Storacha Backup & Restore React widget with WebAuthN-varsig UCAN signing/verification (Ed25519/P-256).
179
+ - [ ] v0.7.3 (May 2026): Storacha Backup & Restore React widget with WebAuthN-varsig UCAN delegation (Ed25519/P-256).
180
+ - [ ] v0.7.4 (May 2026): UI enhancement for the Storacha Backup & Restore widget (timestamped backup restore and management).
181
+ - [ ] v0.8.0 (Jun 2026): Upgrade to UCAN 1.0 support.
182
+ - [ ] v0.9.0 (Jul 2026): Social backup between devices with DKG (decentralized key generation).
183
+ - [ ] v0.10.0 (Aug 2027): WebAuthN + Roaming Credentials: Have a browser and a mobile with one Yubikey creating one and the same DID and replicating the same OrbitDB
184
+
185
+ Read more on Medium: [Bridging OrbitDB with Storacha: Decentralized Database Backups](https://medium.com/@akashjana663/bridging-orbitdb-with-storacha-decentralized-database-backups-44c7bee5c395)
186
+
187
+ ## Installation
188
+
189
+ Install the package via npm:
190
+
191
+ ```bash
192
+ npm install @le-space/orbitdb-storage-bridge
193
+ ```
194
+
195
+ ## Environment Setup
196
+
197
+ `STORACHA_KEY` and `STORACHA_PROOF` in `.env` are still what the code reads, and existing credentials still parse — but there is no longer a service to present them to, and no way to mint new ones: the console and the quickstart docs are gone (see [Status: Storacha sunset](#status-storacha-sunset-may-2026)). The test suite's in-memory modes run without credentials; see `test/README.md`.
198
+
199
+ ## Demo
200
+
201
+ ### NodeJS Demo Scripts (full backup with Manifest, Identity and AccessController and entries blocks)
202
+
203
+ They back up to Aleph by default, which takes an upload without an account, so
204
+ they run straight after cloning. `STORAGE=pinata` and `STORAGE=lighthouse`
205
+ switch to the paid services and read their keys from the environment — see
206
+ [`examples/storage.js`](examples/storage.js).
207
+
208
+ ```sh
209
+ node examples/backup-demo.js # prints the backup's CID
210
+ BACKUP_CID=<cid> node examples/restore-demo.js # restores it on a fresh node
211
+ ```
212
+
213
+ - `node` [`examples/demo.js`](examples/demo.js) - Complete backup/restore cycle, including what stops the second node from writing
214
+ - `node` [`examples/backup-demo.js`](examples/backup-demo.js) - Backup only; prints the CID the restore needs
215
+ - `node` [`examples/restore-demo.js`](examples/restore-demo.js) - Restore from that CID onto a node that has never seen the database
216
+ - `node` [`examples/demo-different-identity.js`](examples/demo-different-identity.js) - Different identities with access control enforcement
217
+ - `node` [`examples/demo-shared-identities.js`](examples/demo-shared-identities.js) - Shared identity backup/restore scenarios
218
+
219
+ An Aleph upload is not kept: staying stored takes a wallet-signed STORE message
220
+ this library does not send, so restore what you back up while the demo is still
221
+ running.
222
+
223
+ The scripts written against Storacha's space and UCAN model are in
224
+ [`examples/storacha/`](examples/storacha/README.md). None of them runs end to
225
+ end since the uploads stopped, and the README there says what replaced each.
226
+
227
+ ### Svelte Components
228
+
229
+ For browser-based integration, this project includes Svelte components for authentication, backup/restore, P2P replication, and WebAuthn biometric authentication. See [**SVELTE-COMPONENTS.md**](SVELTE-COMPONENTS.md) for complete documentation of all available components and demonstrations.
230
+
231
+ That browser side is older than this repository's copy of it, and the UCAN delegation work now sits on a branch. [docs/STORACHA-UI-HISTORY.md](docs/STORACHA-UI-HISTORY.md) records what existed, what it could do, and where each piece is today.
232
+
233
+ ## How It Works
234
+
235
+ 1. **Extract Blocks** - Separates OrbitDB database into individual components (log entries, manifest, identities, access controls)
236
+ 2. **Upload to Storacha** - Each block is uploaded separately to IPFS/Filecoin via Storacha
237
+ 3. **Block Discovery** - Lists all files in Storacha space using Storacha SDK APIs
238
+ 4. **CID Bridging** - Converts between Storacha CIDs (`bafkre*`) and OrbitDB CIDs (`zdpu*`)
239
+ 5. **Reconstruct Database** - Reassembles blocks and opens database with original identity
240
+
241
+ ## Restore Mechanism
242
+
243
+ The restore process uses a **ipfs-p2p-first approach with ipfs-http-gateway fallback** for downloading backups for restore. File listing and metadata discovery are currently performed via the Storacha SDK (using Storacha gateway API). We are working on an **IPNS-based mechanism** to find the latest heads blocks and OrbitDB address directly from the IPFS network via IPNS, eliminating the need to list all files via the centralized Storacha gateway API.
244
+
245
+ ## Logging
246
+
247
+ The library uses **@libp2p/logger** for consistent logging across the libp2p ecosystem. Control logging with the `DEBUG` environment variable:
248
+
249
+ **Node.js:**
250
+ ```bash
251
+ # Enable all logs from this library (the namespace kept its old name)
252
+ DEBUG=libp2p:orbitdb-storacha:* node your-script.js
253
+
254
+ # Enable specific components
255
+ DEBUG=libp2p:orbitdb-storacha:bridge node your-script.js
256
+
257
+ # Enable all libp2p logs (includes this library + libp2p internals)
258
+ DEBUG=libp2p:* node your-script.js
259
+ ```
260
+
261
+ **Browser:**
262
+ ```javascript
263
+ // In browser console or before loading the application
264
+ localStorage.setItem('debug', 'libp2p:orbitdb-storacha:*')
265
+ // Then refresh the page
266
+ ```
267
+
268
+ The logger supports printf-style formatting:
269
+ - `%s` - string
270
+ - `%d` - number
271
+ - `%o` - object
272
+ - `%p` - peer ID
273
+ - `%b` - base58btc encoded data
274
+ - `%t` - base32 encoded data
275
+
276
+ ## Testing
277
+
278
+ See `test/README.md` for detailed test documentation, modes (in-memory vs production),
279
+ and how to run each suite.
280
+
281
+ ## Contributing
282
+
283
+ 1. Fork the repository
284
+ 2. Create a feature branch
285
+ 3. Add tests for new functionality
286
+ 4. Submit a pull request
287
+
288
+ ## License
289
+
290
+ MIT License