OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-did-peer commits / be9daaf

atproto-did-peer 0.1.0 — extract the keyless direction-free P2P reader as a shared module
The announce-push + event-driven-reconcile + read-view primitive, lifted out of atproto-bridge (did-peer.js) so atproto-bridge, atproto-relay AND favela share ONE copy instead of duplicating it (per the "should this be a module?" rule). Adds a keyless read surface (ready/getRepo/getRecord/listRecords/getLatestCommit/collections/ subscribeRepos) over the already-reconciled verified head. Transport-agnostic: the consumer owns the swarm (join discoveryTopic(did), attach(conn) per connection) and supplies verifyKey. Live-proven: test/read-live.mjs reads wj62 over the real swarm (verifyKey resolved from PLC) — collections, getRecord, 30 listRecords, an 11.7KB DID-key-verified CAR. GOTCHA (consumers, incl. favela): create the Corestore via atproto-store's exported openCorestore, NOT `new Corestore` from a separately-installed corestore — atproto-store is a file: dep with its own nested corestore copy, so RepoStore's `instanceof Corestore` fails against a foreign copy ("path argument must be of type string, received undefined"). NEXT: favela consumes this + wraps it as the atcute XRPC handler; migrate the live bridge (PeerFront/PeerRouter) + relay onto it as a separate careful step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
be9daaf85cf4bd3bfaad33b48e07eed28f2a3324
by plankatron <fleeky@gmail.com> · 2026-07-14T01:50:43.000Z

Changed files (6) +1480 -0

.gitignore +2 -0
……@@ -0,0 +1,2 @@
1node_modules/
2*.log
index.js +1 -0
……@@ -0,0 +1 @@
1export { DidPeer, ANNOUNCE_PROTOCOL } from './lib/did-peer.js'
lib/did-peer.js +216 -0
……@@ -0,0 +1,216 @@
1// DidPeer — the corrected, direction-free P2P primitive for an atproto DID's data (repo + firehose
2// Hypercores), extracted from atproto-bridge as a shared module (audited vs keet + holepunch,
3// 2026-07-13). A DID's data lives in a swarm keyed by discoveryTopic(did); every participant —
4// signing device, availability relay/seedbox, read/HTTP bridge, favela client — is the SAME primitive.
5// It is NOT a "front the origin by serverKey" client: it replicates the DID's cores from WHOEVER has
6// them and serves the freshest commit that VERIFIES against the DID key.
7//
8// Corrections baked in (see atproto-bridge memory/feedback_p2p-no-directionality-event-driven):
9// - ANNOUNCE, don't DERIVE / get-coords-PULL: on connect a holder PUSHES {repoKey,firehoseKey,lengths}
10// over a protomux channel (one-mux-per-connection, keet model). No round-trip, no serverKey.
11// - EVENT-DRIVEN head reconciliation: the served head re-derives on the firehose core's 'append'
12// (fires on local append AND on replicated download) — never a data poll.
13// - Auth mandatory: the DID topic is unauthenticated in ANY discovery scheme; trust comes from
14// verifying the served repo's signed commit against the DID signing key (verifyKey).
15//
16// Transport-agnostic: the CONSUMER owns the swarm (joins discoveryTopic(did), and on each 'connection'
17// calls didPeer.attach(conn)). The consumer also supplies verifyKey (resolve from the DID doc / PLC).
18
19import b4a from 'b4a'
20import c from 'compact-encoding'
21import Protomux from 'protomux'
22import { RepoStore } from 'atproto-store/lib/repo-store.js'
23import { FirehoseSequencer } from 'atproto-store/lib/sequencer.js'
24import { decodeCommitFrame } from 'atproto-store/lib/firehose.js'
25import { getRepoFromCommit, getRecord as rvGetRecord, listRecords as rvListRecords } from 'atproto-store/lib/read-view.js'
26import { readCar, loadCommit } from 'atproto-repo/lib/repo.js'
27import { verifyCommit, commitCid } from 'atproto-repo/lib/commit.js'
28
29const ANNOUNCE_PROTOCOL = 'atproto/did-announce/v1'
30const toKey = (k) => (b4a.isBuffer(k) ? k : b4a.from(k, 'hex'))
31
32export class DidPeer {
33 // corestore: a Corestore (cores are global by key). did: the DID. verifyKey: its signing pubkey
34 // (Uint8Array) — REQUIRED to accept a served head. onHead: (head) => void on every NEW verified
35 // head. onError: optional (err) => void.
36 constructor (corestore, { did, verifyKey, onHead = null, onError = null } = {}) {
37 if (!corestore) throw new Error('DidPeer: corestore required')
38 if (!did) throw new Error('DidPeer: did required')
39 if (!verifyKey) throw new Error('DidPeer: verifyKey (DID signing pubkey) required — auth is mandatory')
40 this.corestore = corestore
41 this.did = did
42 this.verifyKey = verifyKey
43 this._onHead = onHead
44 this._onError = onError
45 this.repo = null
46 this.seq = null
47 this._repoKey = null
48 this._firehoseKey = null
49 this._channels = new Set()
50 this.head = null
51 this._opening = null
52 }
53
54 // This node HOLDS the cores (a signing device, a relay that already seeded, or a bootstrap). Open
55 // them so we can serve + announce. Idempotent.
56 async provide ({ repoKey, firehoseKey } = {}) { return this._openCores(repoKey, firehoseKey) }
57
58 async _openCores (repoKey, firehoseKey) {
59 if (this.repo) return
60 if (this._opening) return this._opening
61 this._opening = (async () => {
62 this._repoKey = toKey(repoKey)
63 this._firehoseKey = toKey(firehoseKey)
64 this.repo = await new RepoStore(this.corestore, { key: this._repoKey }).ready()
65 this.seq = await new FirehoseSequencer(this.corestore.get({ key: this._firehoseKey })).ready()
66 // FULL seed so this node can serve the cores to others (download all + follow appends) — this is
67 // the "each peer seeds" torrent behaviour; a read-only consumer that does NOT want to seed can
68 // subclass/override, but seeding-by-default is the P2P-native contribution posture.
69 const seed = (core) => { const pull = () => { try { core.download({ start: 0, end: -1 }) } catch {} }; pull(); core.on('append', pull) }
70 seed(this.repo.core); seed(this.seq.core)
71 // EVENT-DRIVEN: re-derive the served head on every firehose append (local or replicated), and
72 // re-announce the new length to connected peers. No poll loop.
73 this.seq.core.on('append', () => { this._reconcile(); this._announceAll() })
74 await this._reconcile()
75 })()
76 try { await this._opening } finally { this._opening = null }
77 }
78
79 // Wire a swarm connection: replicate the corestore + open the announce channel. Symmetric — both
80 // sides call attach(); whoever HOLDS the cores announces, whoever lacks them learns from the announce.
81 attach (conn) {
82 try { this.corestore.replicate(conn) } catch (e) { this._fail(e) }
83 const mux = Protomux.from(conn)
84 const chan = mux.createChannel({
85 protocol: ANNOUNCE_PROTOCOL,
86 onopen: () => { if (this.repo) this._announceTo(chan) }, // ANNOUNCE-PUSH on open
87 onclose: () => this._channels.delete(chan)
88 })
89 if (!chan) return // already open on this mux
90 chan._announce = chan.addMessage({
91 encoding: c.json,
92 onmessage: (a) => this._onannounce(a).catch((e) => this._fail(e))
93 })
94 chan.open()
95 this._channels.add(chan)
96 if (this.repo) this._announceTo(chan)
97 }
98
99 _announceTo (chan) {
100 if (!this.repo || !chan._announce) return
101 try {
102 chan._announce.send({
103 did: this.did,
104 repoKey: b4a.toString(this._repoKey, 'hex'),
105 firehoseKey: b4a.toString(this._firehoseKey, 'hex'),
106 repoLength: this.repo.core.length,
107 firehoseLength: this.seq.core.length
108 })
109 } catch (e) { this._fail(e) }
110 }
111
112 _announceAll () { for (const chan of this._channels) this._announceTo(chan) }
113
114 async _onannounce (a) {
115 if (!a || a.did !== this.did || !a.repoKey || !a.firehoseKey) return
116 if (!this.repo) {
117 await this._openCores(a.repoKey, a.firehoseKey)
118 this._announceAll() // we can help seed now — tell peers we have them too (symmetric)
119 }
120 // The announce is a HINT (peer says its firehose is at length N). Replication pushes the blocks;
121 // we react to the 'append' event to reconcile. One-shot update() nudges the fetch (event-triggered
122 // on announce, NOT a poll loop).
123 if (this.seq) this.seq.core.update().catch(() => {})
124 }
125
126 // The served head = the freshest signed commit that VERIFIES against the DID key. Re-derived on
127 // firehose 'append'. Rejects an unverifiable head (can't be tricked into serving a forged repo).
128 async _reconcile () {
129 if (!this.seq || this.seq.core.length === 0) return
130 try {
131 const { body } = decodeCommitFrame(await this.seq.core.get(this.seq.core.length - 1))
132 const signed = loadCommit(await readCar(body.blocks)).value
133 if (!verifyCommit(signed, this.verifyKey)) return
134 const rev = signed.rev
135 if (this.head && this.head.rev === rev) return // no change
136 this.head = { rev, cid: commitCid(signed).toString(), signed }
137 if (this._onHead) this._onHead(this.head)
138 } catch (e) { this._fail(e) }
139 }
140
141 _fail (e) { if (this._onError) this._onError(e) }
142
143 // ---- keyless read surface (from the replicated repo/firehose; no signing) ----
144 // Wait until a verified head exists (cores replicated + a commit that verifies against the DID key).
145 async ready ({ timeout = 20000 } = {}) {
146 if (this.head) return this.head
147 const end = Date.now() + timeout
148 while (Date.now() < end) {
149 if (this.head) return this.head
150 await new Promise((r) => setTimeout(r, 100))
151 }
152 return null
153 }
154
155 // com.atproto.sync.getRepo -> keyless signed CAR (records rebuilt from the replicated repo, signature
156 // from the verified firehose commit; getRepoFromCommit guards data-root integrity).
157 async getRepo () {
158 if (!this.repo || !this.head) throw new Error(`DidPeer: no verified head yet for ${this.did}`)
159 return getRepoFromCommit(this.repo, this.head.signed)
160 }
161
162 // com.atproto.repo.getRecord
163 getRecord (collection, rkey) {
164 if (!this.repo) return null
165 return rvGetRecord(this.repo, collection, rkey, { did: this.did })
166 }
167
168 // com.atproto.repo.listRecords
169 listRecords (collection) {
170 if (!this.repo) return []
171 return rvListRecords(this.repo, collection, { did: this.did })
172 }
173
174 // com.atproto.sync.getLatestCommit -> { cid, rev } from the verified head (keyless).
175 getLatestCommit () {
176 if (!this.head) return null
177 return { cid: this.head.cid, rev: this.head.rev }
178 }
179
180 // com.atproto.sync.subscribeRepos -> the peer's own signed firehose frames (cursor=0 backfills).
181 subscribeRepos (cursor = 0, opts) {
182 if (!this.seq) throw new Error(`DidPeer: cores not open for ${this.did}`)
183 return this.seq.subscribe(cursor, opts)
184 }
185
186 // Distinct collection NSIDs present in the replicated repo (keys are "<collection>/<rkey>").
187 async collections () {
188 if (!this.repo) return []
189 const set = new Set()
190 for (const r of await this.repo.records()) {
191 const i = r.key.indexOf('/')
192 if (i > 0) set.add(r.key.slice(0, i))
193 }
194 return [...set]
195 }
196
197 status () {
198 return {
199 did: this.did,
200 hasCores: !!this.repo,
201 repoLength: this.repo ? this.repo.core.length : 0,
202 firehoseLength: this.seq ? this.seq.core.length : 0,
203 head: this.head ? { rev: this.head.rev, cid: this.head.cid } : null,
204 channels: this._channels.size
205 }
206 }
207
208 async close () {
209 for (const chan of this._channels) { try { chan.close() } catch {} }
210 this._channels.clear()
211 if (this.seq) { try { await this.seq.close() } catch {} }
212 if (this.repo) { try { await this.repo.close() } catch {} }
213 }
214}
215
216export { ANNOUNCE_PROTOCOL }
package-lock.json +1185 -0
……@@ -0,0 +1,1185 @@
1{
2 "name": "atproto-did-peer",
3 "version": "0.1.0",
4 "lockfileVersion": 3,
5 "requires": true,
6 "packages": {
7 "": {
8 "name": "atproto-did-peer",
9 "version": "0.1.0",
10 "dependencies": {
11 "atproto-repo": "file:../atproto-repo",
12 "atproto-store": "file:../atproto-store",
13 "b4a": "^1.8.1",
14 "compact-encoding": "^2.19.0",
15 "protomux": "^3.11.0"
16 },
17 "devDependencies": {
18 "atproto-identity": "file:../atproto-identity",
19 "corestore": "^7.4.0",
20 "hyperswarm": "^4.11.0"
21 }
22 },
23 "../atproto-identity": {
24 "version": "0.0.1",
25 "dev": true,
26 "hasInstallScript": true,
27 "dependencies": {
28 "@ipld/dag-cbor": "^9.2.1",
29 "@noble/curves": "^1.6.0",
30 "@noble/hashes": "^1.5.0",
31 "@scure/bip32": "^1.5.0",
32 "@scure/bip39": "^1.4.0",
33 "hypercore-crypto": "^3.0.0",
34 "keet-identity-key": "^3.2.0",
35 "multiformats": "^13.3.0"
36 },
37 "devDependencies": {
38 "brittle": "^4.0.2"
39 }
40 },
41 "../atproto-repo": {
42 "version": "0.0.1",
43 "hasInstallScript": true,
44 "dependencies": {
45 "@ipld/car": "^5.4.0",
46 "@ipld/dag-cbor": "^9.2.1",
47 "@noble/curves": "^1.9.7",
48 "@noble/hashes": "^1.5.0",
49 "multiformats": "^13.3.0"
50 },
51 "devDependencies": {
52 "atproto-identity": "file:../atproto-identity",
53 "brittle": "^4.0.2"
54 }
55 },
56 "../atproto-store": {
57 "version": "0.0.1",
58 "dependencies": {
59 "@ipld/dag-cbor": "^9.2.1",
60 "atproto-repo": "file:../atproto-repo",
61 "b4a": "^1.6.0",
62 "corestore": "^7.4.0",
63 "hyperbee": "^2.20.0",
64 "random-access-memory": "^6.2.0"
65 },
66 "devDependencies": {
67 "brittle": "^4.0.2"
68 }
69 },
70 "node_modules/@hyperswarm/secret-stream": {
71 "version": "6.9.1",
72 "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.9.1.tgz",
73 "integrity": "sha512-xb0S5y3YJwBakD77JOGBHlBxdp63mHClZoXBYoLv+9wH8e054ESKlmQptWqjJK5dv5VMUIVYOJB4MaOpB0JdGw==",
74 "dev": true,
75 "license": "Apache-2.0",
76 "dependencies": {
77 "b4a": "^1.1.0",
78 "hypercore-crypto": "^3.3.1",
79 "noise-curve-ed": "^2.0.1",
80 "noise-handshake": "^4.0.0",
81 "sodium-secretstream": "^1.1.0",
82 "sodium-universal": "^5.0.0",
83 "streamx": "^2.14.0",
84 "timeout-refresh": "^2.0.0",
85 "unslab": "^1.3.0"
86 }
87 },
88 "node_modules/adaptive-timeout": {
89 "version": "1.0.1",
90 "resolved": "https://registry.npmjs.org/adaptive-timeout/-/adaptive-timeout-1.0.1.tgz",
91 "integrity": "sha512-+seGiBtHqbnyZ0Quq/ZGxxwP66153WBABawa07/QeyuPFzbduPBjiGQAyCiriiLDzt3dkbMBskSlfqtRwblK8Q==",
92 "dev": true,
93 "license": "Apache-2.0",
94 "dependencies": {
95 "xache": "^1.2.1"
96 }
97 },
98 "node_modules/atproto-identity": {
99 "resolved": "../atproto-identity",
100 "link": true
101 },
102 "node_modules/atproto-repo": {
103 "resolved": "../atproto-repo",
104 "link": true
105 },
106 "node_modules/atproto-store": {
107 "resolved": "../atproto-store",
108 "link": true
109 },
110 "node_modules/b4a": {
111 "version": "1.8.1",
112 "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz",
113 "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==",
114 "license": "Apache-2.0",
115 "peerDependencies": {
116 "react-native-b4a": "*"
117 },
118 "peerDependenciesMeta": {
119 "react-native-b4a": {
120 "optional": true
121 }
122 }
123 },
124 "node_modules/bare-addon-resolve": {
125 "version": "1.10.0",
126 "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.10.0.tgz",
127 "integrity": "sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA==",
128 "dev": true,
129 "license": "Apache-2.0",
130 "dependencies": {
131 "bare-module-resolve": "^1.10.0",
132 "bare-semver": "^1.0.0"
133 },
134 "peerDependencies": {
135 "bare-url": "*"
136 },
137 "peerDependenciesMeta": {
138 "bare-url": {
139 "optional": true
140 }
141 }
142 },
143 "node_modules/bare-ansi-escapes": {
144 "version": "2.2.3",
145 "resolved": "https://registry.npmjs.org/bare-ansi-escapes/-/bare-ansi-escapes-2.2.3.tgz",
146 "integrity": "sha512-02ES4/E2RbrtZSnHJ9LntBhYkLA6lPpSEeP8iqS3MccBIVhVBlEmruF1I7HZqx5Q8aiTeYfQVeqmrU9YO2yYoQ==",
147 "dev": true,
148 "license": "Apache-2.0",
149 "dependencies": {
150 "bare-stream": "^2.6.5"
151 },
152 "peerDependencies": {
153 "bare-buffer": "*"
154 },
155 "peerDependenciesMeta": {
156 "bare-buffer": {
157 "optional": true
158 }
159 }
160 },
161 "node_modules/bare-assert": {
162 "version": "1.2.0",
163 "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz",
164 "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==",
165 "dev": true,
166 "license": "Apache-2.0",
167 "dependencies": {
168 "bare-inspect": "^3.1.2"
169 }
170 },
171 "node_modules/bare-events": {
172 "version": "2.9.1",
173 "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz",
174 "integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==",
175 "dev": true,
176 "license": "Apache-2.0",
177 "peerDependencies": {
178 "bare-abort-controller": "*"
179 },
180 "peerDependenciesMeta": {
181 "bare-abort-controller": {
182 "optional": true
183 }
184 }
185 },
186 "node_modules/bare-fs": {
187 "version": "4.7.4",
188 "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.4.tgz",
189 "integrity": "sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==",
190 "dev": true,
191 "license": "Apache-2.0",
192 "dependencies": {
193 "bare-events": "^2.5.4",
194 "bare-path": "^3.0.0",
195 "bare-stream": "^2.6.4",
196 "bare-url": "^2.2.2",
197 "fast-fifo": "^1.3.2"
198 },
199 "engines": {
200 "bare": ">=1.16.0"
201 },
202 "peerDependencies": {
203 "bare-buffer": "*"
204 },
205 "peerDependenciesMeta": {
206 "bare-buffer": {
207 "optional": true
208 }
209 }
210 },
211 "node_modules/bare-inspect": {
212 "version": "3.1.4",
213 "resolved": "https://registry.npmjs.org/bare-inspect/-/bare-inspect-3.1.4.tgz",
214 "integrity": "sha512-jfW5KRA84o3REpI6Vr4nbvMn+hqVAw8GU1mMdRwUsY5yJovQamxYeKGVKGqdzs+8ZbG4jRzGUXP/3Ji/DnqfPg==",
215 "dev": true,
216 "license": "Apache-2.0",
217 "dependencies": {
218 "bare-ansi-escapes": "^2.1.0",
219 "bare-type": "^1.0.0"
220 },
221 "engines": {
222 "bare": ">=1.18.0"
223 }
224 },
225 "node_modules/bare-module-resolve": {
226 "version": "1.12.2",
227 "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.2.tgz",
228 "integrity": "sha512-j+hiD5k99qec4KjJvYsI67q5AOBifmy9JG3oeMVxTmvrhn2sIdp8StrUvZu4YNgwTpO+NhniQG16N1ETDe1k5w==",
229 "dev": true,
230 "license": "Apache-2.0",
231 "dependencies": {
232 "bare-semver": "^1.0.0"
233 },
234 "peerDependencies": {
235 "bare-url": "*"
236 },
237 "peerDependenciesMeta": {
238 "bare-url": {
239 "optional": true
240 }
241 }
242 },
243 "node_modules/bare-path": {
244 "version": "3.1.1",
245 "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.1.tgz",
246 "integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==",
247 "dev": true,
248 "license": "Apache-2.0"
249 },
250 "node_modules/bare-semver": {
251 "version": "1.1.0",
252 "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.1.0.tgz",
253 "integrity": "sha512-1Hw5qJ7hXdVt3uPUqjeFTuxyvBUJauvz5A1I2jk8gzjZMHp04n//6nV9MDbG9CMw78JHY2lGV0w6s//LrASm2w==",
254 "dev": true,
255 "license": "Apache-2.0"
256 },
257 "node_modules/bare-stream": {
258 "version": "2.13.3",
259 "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.3.tgz",
260 "integrity": "sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==",
261 "dev": true,
262 "license": "Apache-2.0",
263 "dependencies": {
264 "b4a": "^1.8.1",
265 "streamx": "^2.25.0",
266 "teex": "^1.0.1"
267 },
268 "peerDependencies": {
269 "bare-abort-controller": "*",
270 "bare-buffer": "*",
271 "bare-events": "*"
272 },
273 "peerDependenciesMeta": {
274 "bare-abort-controller": {
275 "optional": true
276 },
277 "bare-buffer": {
278 "optional": true
279 },
280 "bare-events": {
281 "optional": true
282 }
283 }
284 },
285 "node_modules/bare-type": {
286 "version": "1.1.0",
287 "resolved": "https://registry.npmjs.org/bare-type/-/bare-type-1.1.0.tgz",
288 "integrity": "sha512-LdtnnEEYldOc87Dr4GpsKnStStZk3zfgoEMXy8yvEZkXrcCv9RtYDrUYWFsBQHtaB0s1EUWmcvS6XmEZYIj3Bw==",
289 "dev": true,
290 "license": "Apache-2.0",
291 "engines": {
292 "bare": ">=1.2.0"
293 }
294 },
295 "node_modules/bare-url": {
296 "version": "2.4.5",
297 "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz",
298 "integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==",
299 "dev": true,
300 "license": "Apache-2.0",
301 "dependencies": {
302 "bare-path": "^3.0.0"
303 }
304 },
305 "node_modules/big-sparse-array": {
306 "version": "1.0.3",
307 "resolved": "https://registry.npmjs.org/big-sparse-array/-/big-sparse-array-1.0.3.tgz",
308 "integrity": "sha512-6RjV/3mSZORlMdpUaQ6rUSpG637cZm0//E54YYGtQg1c1O+AbZP8UTdJ/TchsDZcTVLmyWZcseBfp2HBeXUXOQ==",
309 "dev": true,
310 "license": "MIT"
311 },
312 "node_modules/bits-to-bytes": {
313 "version": "1.3.0",
314 "resolved": "https://registry.npmjs.org/bits-to-bytes/-/bits-to-bytes-1.3.0.tgz",
315 "integrity": "sha512-OJoHTpFXS9bXHBCekGTByf3MqM8CGblBDIduKQeeVVeiU9dDWywSSirXIBYGgg3d1zbVuvnMa1vD4r6PA0kOKg==",
316 "dev": true,
317 "license": "ISC",
318 "dependencies": {
319 "b4a": "^1.5.0"
320 }
321 },
322 "node_modules/blind-relay": {
323 "version": "1.6.1",
324 "resolved": "https://registry.npmjs.org/blind-relay/-/blind-relay-1.6.1.tgz",
325 "integrity": "sha512-38YmKCl/m9NcTkwueBbcGIt9Zx3IT/Q9Nsluu6C5Gur6PqfE0zWPhPwCzia1hri/g0ICYxrqkgLtEaoWD5WeSQ==",
326 "dev": true,
327 "license": "Apache-2.0",
328 "dependencies": {
329 "b4a": "^1.6.4",
330 "bare-events": "^2.2.0",
331 "bits-to-bytes": "^1.3.0",
332 "compact-encoding": "^3.0.0",
333 "compact-encoding-bitfield": "^1.0.0",
334 "protomux": "^3.5.1",
335 "sodium-universal": "^5.0.0",
336 "streamx": "^2.15.1"
337 }
338 },
339 "node_modules/blind-relay/node_modules/compact-encoding": {
340 "version": "3.3.0",
341 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
342 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
343 "dev": true,
344 "license": "Apache-2.0",
345 "dependencies": {
346 "b4a": "^1.3.0"
347 }
348 },
349 "node_modules/bogon": {
350 "version": "1.3.0",
351 "resolved": "https://registry.npmjs.org/bogon/-/bogon-1.3.0.tgz",
352 "integrity": "sha512-04tu0G/v0f2HPuQlSfhO635WwHDBCaITJ490rhxH9ttUlgPqOirZVKV02YB6NvPf5VkmbqJCm3bnZwrPk/eDSg==",
353 "dev": true,
354 "license": "MIT",
355 "dependencies": {
356 "compact-encoding": "^3.0.0",
357 "compact-encoding-net": "^1.2.0"
358 }
359 },
360 "node_modules/bogon/node_modules/compact-encoding": {
361 "version": "3.3.0",
362 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
363 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
364 "dev": true,
365 "license": "Apache-2.0",
366 "dependencies": {
367 "b4a": "^1.3.0"
368 }
369 },
370 "node_modules/compact-encoding": {
371 "version": "2.19.2",
372 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-2.19.2.tgz",
373 "integrity": "sha512-/YjhHQE/5L4F7l5Bht69dRbP9RV6zoJPeowi8bMKQxNKe3Nh6hOY8pBGoVE9fz5GaWfEd8fWJ2aU9sB4KZuMYg==",
374 "license": "Apache-2.0",
375 "dependencies": {
376 "b4a": "^1.3.0"
377 }
378 },
379 "node_modules/compact-encoding-bitfield": {
380 "version": "1.1.0",
381 "resolved": "https://registry.npmjs.org/compact-encoding-bitfield/-/compact-encoding-bitfield-1.1.0.tgz",
382 "integrity": "sha512-F6wliSKHi50BsBStmnsRJAzJgYSIYzdfSe3M0oHj4uQ1RcctJK/NQVD7wF51bj/DBMne2i5gUxrGUFkNZQns5w==",
383 "dev": true,
384 "license": "Apache-2.0",
385 "dependencies": {
386 "compact-encoding": "^3.0.0"
387 }
388 },
389 "node_modules/compact-encoding-bitfield/node_modules/compact-encoding": {
390 "version": "3.3.0",
391 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
392 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
393 "dev": true,
394 "license": "Apache-2.0",
395 "dependencies": {
396 "b4a": "^1.3.0"
397 }
398 },
399 "node_modules/compact-encoding-net": {
400 "version": "1.3.0",
401 "resolved": "https://registry.npmjs.org/compact-encoding-net/-/compact-encoding-net-1.3.0.tgz",
402 "integrity": "sha512-HIYjL3aMiSENApR691aMLngXt6rkTHb9HUkEukcx3YwIZpoMUVXHXyjBzoo9kVwC7KakooBA1RRWb46Cu6qtAQ==",
403 "dev": true,
404 "license": "Apache-2.0",
405 "dependencies": {
406 "compact-encoding": "^3.0.0"
407 }
408 },
409 "node_modules/compact-encoding-net/node_modules/compact-encoding": {
410 "version": "3.3.0",
411 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
412 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
413 "dev": true,
414 "license": "Apache-2.0",
415 "dependencies": {
416 "b4a": "^1.3.0"
417 }
418 },
419 "node_modules/corestore": {
420 "version": "7.11.0",
421 "resolved": "https://registry.npmjs.org/corestore/-/corestore-7.11.0.tgz",
422 "integrity": "sha512-zGlF6dBZ9bvyRliz6g+NW0tGRwGYmmc84o1TARbXOJ+fPRXeKTkVzVV95eWIJEU3+6WBUbcvIBQKmKiNmiTAdg==",
423 "dev": true,
424 "license": "MIT",
425 "dependencies": {
426 "b4a": "^1.6.7",
427 "bare-events": "^2.8.3",
428 "hypercore": "^11.32.0",
429 "hypercore-crypto": "^3.4.2",
430 "hypercore-errors": "^1.4.0",
431 "hypercore-id-encoding": "^1.3.0",
432 "ready-resource": "^1.1.1",
433 "sodium-universal": "^5.0.1",
434 "streamx": "^2.26.0",
435 "which-runtime": "^1.2.1"
436 }
437 },
438 "node_modules/device-file": {
439 "version": "2.3.1",
440 "resolved": "https://registry.npmjs.org/device-file/-/device-file-2.3.1.tgz",
441 "integrity": "sha512-bmON44lwxJPle9N2OcH4tqM44pMGZKT8G6OkzXkz0urvqQ9LKkoQdTS6w0ztYfmLdUE27R4UUmx0+y2gEz4Jug==",
442 "dev": true,
443 "license": "Apache-2.0",
444 "dependencies": {
445 "b4a": "^1.6.7",
446 "bare-fs": "^4.0.1",
447 "bare-path": "^3.0.0",
448 "fd-lock": "^2.1.0",
449 "fs-native-extensions": "^1.4.0",
450 "ready-resource": "^1.2.0"
451 }
452 },
453 "node_modules/dht-rpc": {
454 "version": "6.27.0",
455 "resolved": "https://registry.npmjs.org/dht-rpc/-/dht-rpc-6.27.0.tgz",
456 "integrity": "sha512-NsfgRlFDQnkA2+H+hJXMPLmBOn/TSIIc0cRMV8q42M4xc1uAXWtpvIIQsONF5tYcYC6px0bslrUGideN1h4S4A==",
457 "dev": true,
458 "license": "MIT",
459 "dependencies": {
460 "adaptive-timeout": "^1.0.1",
461 "b4a": "^1.6.1",
462 "bare-events": "^2.2.0",
463 "compact-encoding": "^3.0.0",
464 "compact-encoding-net": "^1.2.0",
465 "fast-fifo": "^1.1.0",
466 "kademlia-routing-table": "^1.0.1",
467 "nat-sampler": "^1.0.1",
468 "sodium-universal": "^5.0.0",
469 "streamx": "^2.13.2",
470 "time-ordered-set": "^2.0.0",
471 "udx-native": "^1.5.3"
472 }
473 },
474 "node_modules/dht-rpc/node_modules/compact-encoding": {
475 "version": "3.3.0",
476 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
477 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
478 "dev": true,
479 "license": "Apache-2.0",
480 "dependencies": {
481 "b4a": "^1.3.0"
482 }
483 },
484 "node_modules/events-universal": {
485 "version": "1.0.1",
486 "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
487 "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
488 "dev": true,
489 "license": "Apache-2.0",
490 "dependencies": {
491 "bare-events": "^2.7.0"
492 }
493 },
494 "node_modules/fast-fifo": {
495 "version": "1.3.2",
496 "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
497 "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
498 "dev": true,
499 "license": "MIT"
500 },
501 "node_modules/fd-lock": {
502 "version": "2.2.0",
503 "resolved": "https://registry.npmjs.org/fd-lock/-/fd-lock-2.2.0.tgz",
504 "integrity": "sha512-Il4jWBhjjgvUg+z8d0bC7ncXqB42caqKTUpnZ9jpcqiPmw8bkIixt7Kic1czbZPMxAQD/9kEqfZ5Dq77nSll0w==",
505 "dev": true,
506 "license": "Apache-2.0",
507 "dependencies": {
508 "bare-fs": "^4.5.0",
509 "fs-native-extensions": "^1.4.4",
510 "ready-resource": "^1.2.0",
511 "resource-on-exit": "^1.0.0"
512 }
513 },
514 "node_modules/flat-tree": {
515 "version": "1.13.0",
516 "resolved": "https://registry.npmjs.org/flat-tree/-/flat-tree-1.13.0.tgz",
517 "integrity": "sha512-fT3HIuCPwHhFgJ20QYzDHgUG0zMmFg5cHvFiFo5h+QMSJ28TihsEVY0f8HGliuO+pOzmvjMx1odToeaEWkTnyQ==",
518 "dev": true,
519 "license": "MIT"
520 },
521 "node_modules/fs-native-extensions": {
522 "version": "1.5.0",
523 "resolved": "https://registry.npmjs.org/fs-native-extensions/-/fs-native-extensions-1.5.0.tgz",
524 "integrity": "sha512-nuZLFm9mGCxvyi7Llww/J4OyifKCS21nEUTAmnlTZp3FObPOvA32aCedCmt4Z+8yk+caqfClNaSCfn/P7T7FLQ==",
525 "dev": true,
526 "license": "Apache-2.0",
527 "dependencies": {
528 "require-addon": "^1.1.0",
529 "which-runtime": "^1.2.0"
530 }
531 },
532 "node_modules/generate-object-property": {
533 "version": "2.0.0",
534 "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-2.0.0.tgz",
535 "integrity": "sha512-KwuURPyqn2Mz8DdV29pJwQu0Y7tcsbkULr82eeOcY/ZllFK6I9Wm8dsRByIu7CKWlFi9BdW1b3mcXMp/kQBQsw==",
536 "dev": true,
537 "license": "MIT",
538 "dependencies": {
539 "is-property": "^1.0.0"
540 }
541 },
542 "node_modules/generate-string": {
543 "version": "1.0.1",
544 "resolved": "https://registry.npmjs.org/generate-string/-/generate-string-1.0.1.tgz",
545 "integrity": "sha512-IfTY0dKZM43ACyGvXkbG7De7WY7MxTS5VO6Juhe8oJKpCmrYYXoqp/cJMskkpi0k9H8wuXq0H+eI898/BCqvXg==",
546 "dev": true,
547 "license": "MIT"
548 },
549 "node_modules/hypercore": {
550 "version": "11.34.0",
551 "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-11.34.0.tgz",
552 "integrity": "sha512-wXln1nAf4pAOAxxxyWMvN/c2PrOxZSbJnMTeAPKVA4fhhQx/b6DrqfdAfS2vkvcieqRD50EJRwi5179rINheTQ==",
553 "dev": true,
554 "license": "MIT",
555 "dependencies": {
556 "@hyperswarm/secret-stream": "^6.0.0",
557 "b4a": "^1.1.0",
558 "bare-events": "^2.2.0",
559 "big-sparse-array": "^1.0.3",
560 "compact-encoding": "^3.0.0",
561 "fast-fifo": "^1.3.0",
562 "flat-tree": "^1.9.0",
563 "hypercore-crypto": "^3.2.1",
564 "hypercore-errors": "^1.5.0",
565 "hypercore-id-encoding": "^1.2.0",
566 "hypercore-storage": "^3.2.0",
567 "is-options": "^1.0.1",
568 "nanoassert": "^2.0.0",
569 "protomux": "^3.5.0",
570 "quickbit-universal": "^2.2.0",
571 "random-array-iterator": "^1.0.0",
572 "safety-catch": "^1.0.1",
573 "sodium-universal": "^5.0.1",
574 "streamx": "^2.12.4",
575 "unslab": "^1.3.0",
576 "z32": "^1.0.0"
577 }
578 },
579 "node_modules/hypercore-crypto": {
580 "version": "3.7.0",
581 "resolved": "https://registry.npmjs.org/hypercore-crypto/-/hypercore-crypto-3.7.0.tgz",
582 "integrity": "sha512-SWxobptQf2V/+ZLCCDRTXqFzGfTPIkNIuDyLKXpEMfcpJ1/ec94N9aWgylHcWOHmRt14ng/KR7z0BugebWHK9Q==",
583 "dev": true,
584 "license": "MIT",
585 "dependencies": {
586 "b4a": "^1.6.6",
587 "compact-encoding": "^3.0.0",
588 "sodium-universal": "^5.0.0"
589 }
590 },
591 "node_modules/hypercore-crypto/node_modules/compact-encoding": {
592 "version": "3.3.0",
593 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
594 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
595 "dev": true,
596 "license": "Apache-2.0",
597 "dependencies": {
598 "b4a": "^1.3.0"
599 }
600 },
601 "node_modules/hypercore-errors": {
602 "version": "1.5.0",
603 "resolved": "https://registry.npmjs.org/hypercore-errors/-/hypercore-errors-1.5.0.tgz",
604 "integrity": "sha512-5KQ/SuDxsvet+7qWA35Ay6zdD9WyAHQoyWHGcPUTbmJBd300gvNIJoi3oma7kp4TTCSzii6qYumNZe/s0j/saQ==",
605 "dev": true,
606 "license": "Apache-2.0",
607 "dependencies": {
608 "hypercore-id-encoding": "^1.3.0"
609 }
610 },
611 "node_modules/hypercore-id-encoding": {
612 "version": "1.3.0",
613 "resolved": "https://registry.npmjs.org/hypercore-id-encoding/-/hypercore-id-encoding-1.3.0.tgz",
614 "integrity": "sha512-W6sHdGo5h7LXEsoWfKf/KfuROZmZRQDlGqJF2EPHW+noCK66Vvr0+zE6cL0vqQi18s0kQPeN7Sq3QyR0Ytc2VQ==",
615 "dev": true,
616 "license": "Apache-2.0",
617 "dependencies": {
618 "b4a": "^1.5.3",
619 "z32": "^1.0.0"
620 }
621 },
622 "node_modules/hypercore-storage": {
623 "version": "3.2.0",
624 "resolved": "https://registry.npmjs.org/hypercore-storage/-/hypercore-storage-3.2.0.tgz",
625 "integrity": "sha512-i5O5ZMkdZaNAWGuNRXUZjuzv7B41OIhDHUwLCZPjucgVmywY0ZE5PDafu6e5oPuhtghjl6S8q6Jn+POVKN2BvQ==",
626 "dev": true,
627 "license": "Apache-2.0",
628 "dependencies": {
629 "b4a": "^1.6.7",
630 "bare-path": "^3.0.0",
631 "compact-encoding": "^3.1.0",
632 "device-file": "^2.1.2",
633 "flat-tree": "^1.12.1",
634 "hypercore-crypto": "^3.4.2",
635 "hyperschema": "^1.21.0",
636 "index-encoder": "^3.3.2",
637 "resolve-reject-promise": "^1.0.0",
638 "rocksdb-native": "^3.11.0",
639 "scope-lock": "^1.2.4",
640 "streamx": "^2.21.1",
641 "xache": "^1.2.1"
642 }
643 },
644 "node_modules/hypercore-storage/node_modules/compact-encoding": {
645 "version": "3.3.0",
646 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
647 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
648 "dev": true,
649 "license": "Apache-2.0",
650 "dependencies": {
651 "b4a": "^1.3.0"
652 }
653 },
654 "node_modules/hypercore/node_modules/compact-encoding": {
655 "version": "3.3.0",
656 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
657 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
658 "dev": true,
659 "license": "Apache-2.0",
660 "dependencies": {
661 "b4a": "^1.3.0"
662 }
663 },
664 "node_modules/hyperdht": {
665 "version": "6.33.0",
666 "resolved": "https://registry.npmjs.org/hyperdht/-/hyperdht-6.33.0.tgz",
667 "integrity": "sha512-veSvVKptjPTu2di3q5IWI62ZDFzEmTj1QSTAkiXW/cg0+lgMUlwfVWB4dX+WI14xNb54vogVIjA/Ph3KiVuRJQ==",
668 "dev": true,
669 "license": "MIT",
670 "dependencies": {
671 "@hyperswarm/secret-stream": "^6.6.2",
672 "b4a": "^1.3.1",
673 "bare-events": "^2.2.0",
674 "blind-relay": "^1.3.0",
675 "bogon": "^1.0.0",
676 "compact-encoding": "^3.0.0",
677 "dht-rpc": "^6.15.1",
678 "hypercore-crypto": "^3.3.0",
679 "hypercore-id-encoding": "^1.2.0",
680 "hyperdht-address": "^1.0.1",
681 "noise-curve-ed": "^2.0.0",
682 "noise-handshake": "^4.0.0",
683 "record-cache": "^1.1.1",
684 "safety-catch": "^1.0.1",
685 "signal-promise": "^1.0.3",
686 "sodium-universal": "^5.0.1",
687 "streamx": "^2.16.1",
688 "unslab": "^1.3.0",
689 "xache": "^1.1.0"
690 },
691 "bin": {
692 "hyperdht": "bin.js"
693 }
694 },
695 "node_modules/hyperdht-address": {
696 "version": "1.1.1",
697 "resolved": "https://registry.npmjs.org/hyperdht-address/-/hyperdht-address-1.1.1.tgz",
698 "integrity": "sha512-Mu/+7SW2cwvHxMXswa5mOrhrS5BJyntViAuB25k8d8wNtA8eAPs4LaIq6TwN1SS/KQY02h1r+gM8cQeN/k360w==",
699 "dev": true,
700 "license": "Apache-2.0",
701 "dependencies": {
702 "compact-encoding": "^3.0.0",
703 "hyperschema": "^1.20.1"
704 }
705 },
706 "node_modules/hyperdht-address/node_modules/compact-encoding": {
707 "version": "3.3.0",
708 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
709 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
710 "dev": true,
711 "license": "Apache-2.0",
712 "dependencies": {
713 "b4a": "^1.3.0"
714 }
715 },
716 "node_modules/hyperdht/node_modules/compact-encoding": {
717 "version": "3.3.0",
718 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
719 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
720 "dev": true,
721 "license": "Apache-2.0",
722 "dependencies": {
723 "b4a": "^1.3.0"
724 }
725 },
726 "node_modules/hyperschema": {
727 "version": "1.21.0",
728 "resolved": "https://registry.npmjs.org/hyperschema/-/hyperschema-1.21.0.tgz",
729 "integrity": "sha512-lEnIbLTUQf7w6FU6X+R3yUJhBwCzF4ewRnAaYOrPdcVWe1rbOf94PzMiXb5pBKxroCXzlrPLxVujxAsTrrHc8g==",
730 "dev": true,
731 "license": "Apache-2.0",
732 "dependencies": {
733 "bare-fs": "^4.0.1",
734 "compact-encoding": "^3.0.0",
735 "generate-object-property": "^2.0.0",
736 "generate-string": "^1.0.1"
737 }
738 },
739 "node_modules/hyperschema/node_modules/compact-encoding": {
740 "version": "3.3.0",
741 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
742 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
743 "dev": true,
744 "license": "Apache-2.0",
745 "dependencies": {
746 "b4a": "^1.3.0"
747 }
748 },
749 "node_modules/hyperswarm": {
750 "version": "4.17.0",
751 "resolved": "https://registry.npmjs.org/hyperswarm/-/hyperswarm-4.17.0.tgz",
752 "integrity": "sha512-oe86sK961Ueg7rvDN/veFwG8xH+Iv6vObPhGDkPJcDVxk/NduW41ZhAcVDnHzRbm7S0eLU7WaDUvehOYoKSpRQ==",
753 "dev": true,
754 "license": "MIT",
755 "dependencies": {
756 "b4a": "^1.3.1",
757 "bare-events": "^2.2.0",
758 "hyperdht": "^6.21.0",
759 "safety-catch": "^1.0.2",
760 "shuffled-priority-queue": "^2.1.0",
761 "streamx": "^2.22.1",
762 "unslab": "^1.3.0"
763 }
764 },
765 "node_modules/index-encoder": {
766 "version": "3.5.0",
767 "resolved": "https://registry.npmjs.org/index-encoder/-/index-encoder-3.5.0.tgz",
768 "integrity": "sha512-idZ1cxtZz2dRV6rUiaP9Xo99UjXbSzjcMacoQmxUMu/A7fEQcNPngvwDJYeWelQUS5XFlY71/or70lKn6XnwbQ==",
769 "dev": true,
770 "license": "Apache-2.0",
771 "dependencies": {
772 "b4a": "^1.6.4"
773 }
774 },
775 "node_modules/is-options": {
776 "version": "1.0.2",
777 "resolved": "https://registry.npmjs.org/is-options/-/is-options-1.0.2.tgz",
778 "integrity": "sha512-u+Ai74c8Q74aS8BuHwPdI1jptGOT1FQXgCq8/zv0xRuE+wRgSMEJLj8lVO8Zp9BeGb29BXY6AsNPinfqjkr7Fg==",
779 "dev": true,
780 "license": "MIT",
781 "dependencies": {
782 "b4a": "^1.1.1"
783 }
784 },
785 "node_modules/is-property": {
786 "version": "1.0.2",
787 "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
788 "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
789 "dev": true,
790 "license": "MIT"
791 },
792 "node_modules/kademlia-routing-table": {
793 "version": "1.0.6",
794 "resolved": "https://registry.npmjs.org/kademlia-routing-table/-/kademlia-routing-table-1.0.6.tgz",
795 "integrity": "sha512-Ve6jwIlUCYvUzBnXnzVRHDZCFgXURW9gmF3r7n05kZs/2rNbLHXwGdcq0qIaSwdmJCvtosgR4JensnVU65hzNQ==",
796 "dev": true,
797 "license": "MIT",
798 "dependencies": {
799 "bare-events": "^2.2.0"
800 }
801 },
802 "node_modules/nanoassert": {
803 "version": "2.0.0",
804 "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz",
805 "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==",
806 "dev": true,
807 "license": "ISC"
808 },
809 "node_modules/nat-sampler": {
810 "version": "1.0.1",
811 "resolved": "https://registry.npmjs.org/nat-sampler/-/nat-sampler-1.0.1.tgz",
812 "integrity": "sha512-yQvyNN7xbqR8crTKk3U8gRgpcV1Az+vfCEijiHu9oHHsnIl8n3x+yXNHl42M6L3czGynAVoOT9TqBfS87gDdcw==",
813 "dev": true,
814 "license": "MIT"
815 },
816 "node_modules/noise-curve-ed": {
817 "version": "2.1.0",
818 "resolved": "https://registry.npmjs.org/noise-curve-ed/-/noise-curve-ed-2.1.0.tgz",
819 "integrity": "sha512-zAzJx+VwZM3w6EA1hTmDhJfvAnCeBQn/1FAeZ0LtGxCcCtlAK/uJXQVF/eDVUOaAZ286lHlx77WJ+qj9SmsRRg==",
820 "dev": true,
821 "license": "ISC",
822 "dependencies": {
823 "b4a": "^1.1.0",
824 "nanoassert": "^2.0.0",
825 "sodium-universal": "^5.0.0"
826 }
827 },
828 "node_modules/noise-handshake": {
829 "version": "4.2.0",
830 "resolved": "https://registry.npmjs.org/noise-handshake/-/noise-handshake-4.2.0.tgz",
831 "integrity": "sha512-9O/VTNX/E2/AToyMTTDU0J/4WhaXMTdqc2DHs9vf+snoZ0cenSBq0dNYTVV1snYYEkmo6QeRrYMxtqtoYnY+LA==",
832 "dev": true,
833 "license": "Apache-2.0",
834 "dependencies": {
835 "b4a": "^1.1.0",
836 "nanoassert": "^2.0.0",
837 "sodium-universal": "^5.0.0"
838 }
839 },
840 "node_modules/protomux": {
841 "version": "3.11.0",
842 "resolved": "https://registry.npmjs.org/protomux/-/protomux-3.11.0.tgz",
843 "integrity": "sha512-Ze43XaNHbL6zQ/zJwVYvue7Aj8pDB1HNnISsrFhAur3291Y+Iu2fMhOpySD73J/32BoBIUYrhl07lJsBR/fUVA==",
844 "license": "MIT",
845 "dependencies": {
846 "b4a": "^1.3.1",
847 "compact-encoding": "^3.0.0",
848 "queue-tick": "^1.0.0",
849 "safety-catch": "^1.0.1",
850 "unslab": "^1.3.0"
851 }
852 },
853 "node_modules/protomux/node_modules/compact-encoding": {
854 "version": "3.3.0",
855 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
856 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
857 "license": "Apache-2.0",
858 "dependencies": {
859 "b4a": "^1.3.0"
860 }
861 },
862 "node_modules/queue-tick": {
863 "version": "1.0.1",
864 "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
865 "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
866 "license": "MIT"
867 },
868 "node_modules/quickbit-native": {
869 "version": "2.4.8",
870 "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.4.8.tgz",
871 "integrity": "sha512-FcCcqI+nIAWGknqhtrYT5TSD7t/N+Xd8ctM+2PrIIBuwOi5hx0SxAvuPtzLIEMfT/2h9+fhBakUe2uALOHX6yw==",
872 "dev": true,
873 "license": "Apache-2.0",
874 "optional": true,
875 "dependencies": {
876 "require-addon": "^1.1.0"
877 }
878 },
879 "node_modules/quickbit-universal": {
880 "version": "2.2.0",
881 "resolved": "https://registry.npmjs.org/quickbit-universal/-/quickbit-universal-2.2.0.tgz",
882 "integrity": "sha512-w02i1R8n7+6pEKTud8DfF8zbFY9o7RtPlUc3jWbtCkDKvhbx/AvV7oNnz4/TcmsPGpSJS+fq5Ud6RH6+YPvSGg==",
883 "dev": true,
884 "license": "ISC",
885 "dependencies": {
886 "b4a": "^1.6.0",
887 "simdle-universal": "^1.1.0"
888 },
889 "optionalDependencies": {
890 "quickbit-native": "^2.2.0"
891 }
892 },
893 "node_modules/random-array-iterator": {
894 "version": "1.0.0",
895 "resolved": "https://registry.npmjs.org/random-array-iterator/-/random-array-iterator-1.0.0.tgz",
896 "integrity": "sha512-u7xCM93XqKEvPTP6xZp2ehttcAemKnh73oKNf1FvzuVCfpt6dILDt1Kxl1LeBjm2iNIeR49VGFhy4Iz3yOun+Q==",
897 "dev": true,
898 "license": "MIT"
899 },
900 "node_modules/ready-resource": {
901 "version": "1.2.0",
902 "resolved": "https://registry.npmjs.org/ready-resource/-/ready-resource-1.2.0.tgz",
903 "integrity": "sha512-nfcco/8iAFV0M+2PYnmIc+/xY0iRb35d42HFHQ7AfjulbGEAFa+XWpByfwSyeVeiBoMLLFVMv1HixxNCqzSQ1g==",
904 "dev": true,
905 "license": "MIT",
906 "dependencies": {
907 "bare-events": "^2.2.0"
908 }
909 },
910 "node_modules/record-cache": {
911 "version": "1.2.0",
912 "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.2.0.tgz",
913 "integrity": "sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==",
914 "dev": true,
915 "license": "MIT",
916 "dependencies": {
917 "b4a": "^1.3.1"
918 }
919 },
920 "node_modules/refcounter": {
921 "version": "1.0.0",
922 "resolved": "https://registry.npmjs.org/refcounter/-/refcounter-1.0.0.tgz",
923 "integrity": "sha512-1WosVzUy0kPUaPMEtlNDwm99UsteALIhXXR8rerELoa63WkYIXAl0hxgwPFrIYBRWZPGUyekQ04FRtPJ7dHk9w==",
924 "dev": true,
925 "license": "Apache-2.0"
926 },
927 "node_modules/require-addon": {
928 "version": "1.2.0",
929 "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.2.0.tgz",
930 "integrity": "sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA==",
931 "dev": true,
932 "license": "Apache-2.0",
933 "dependencies": {
934 "bare-addon-resolve": "^1.3.0"
935 },
936 "engines": {
937 "bare": ">=1.10.0"
938 }
939 },
940 "node_modules/resolve-reject-promise": {
941 "version": "1.1.0",
942 "resolved": "https://registry.npmjs.org/resolve-reject-promise/-/resolve-reject-promise-1.1.0.tgz",
943 "integrity": "sha512-LWsTOA91AqzBTjSGgX79Tc130pwcBK6xjpJEO+qRT5IKZ6bGnHKcc8QL3upUBcWuU8OTIDzKK2VNSwmmlqvAVg==",
944 "dev": true,
945 "license": "MIT"
946 },
947 "node_modules/resource-on-exit": {
948 "version": "1.0.0",
949 "resolved": "https://registry.npmjs.org/resource-on-exit/-/resource-on-exit-1.0.0.tgz",
950 "integrity": "sha512-ViJwJAknCkLRJRPR+9SISQQ7R5eRgtdIHLJsM2hHx1MweAJbJxJ5XnMjjq0Lc7ZGv44ufzAqds1nKxiVkdy4ag==",
951 "dev": true,
952 "license": "Apache-2.0"
953 },
954 "node_modules/rocksdb-native": {
955 "version": "3.17.2",
956 "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-3.17.2.tgz",
957 "integrity": "sha512-6kijLkb7NrUFCyWQsIxKIU/iQASxdqLDWrteAeXVEq1MJWrJUcXP6MDPRh8Ux7im2sBereDiI/D4vxYV2ia90A==",
958 "dev": true,
959 "license": "Apache-2.0",
960 "dependencies": {
961 "compact-encoding": "^3.0.0",
962 "ready-resource": "^1.0.0",
963 "refcounter": "^1.0.0",
964 "require-addon": "^1.0.2",
965 "resolve-reject-promise": "^1.1.0",
966 "signal-promise": "^1.0.3",
967 "streamx": "^2.16.1"
968 },
969 "engines": {
970 "bare": ">=1.16.0"
971 }
972 },
973 "node_modules/rocksdb-native/node_modules/compact-encoding": {
974 "version": "3.3.0",
975 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
976 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
977 "dev": true,
978 "license": "Apache-2.0",
979 "dependencies": {
980 "b4a": "^1.3.0"
981 }
982 },
983 "node_modules/safety-catch": {
984 "version": "1.0.3",
985 "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.3.tgz",
986 "integrity": "sha512-Zq+J1TefpoEq/HTUabo0YXX5MNvttjWYODGohgPBO2jfko8Wqx3JYMgE823szDFVamdH5PlpByvfiWScTdSYDA==",
987 "license": "MIT"
988 },
989 "node_modules/scope-lock": {
990 "version": "1.2.4",
991 "resolved": "https://registry.npmjs.org/scope-lock/-/scope-lock-1.2.4.tgz",
992 "integrity": "sha512-BpSd8VCuCxW9ZitcdIC/vjs3gMaP9bRBL5nkHcyfX2VrS52n13/rHuBA2xJ/S/4DPuRdAO/Bk8pWd8eD/gHCIA==",
993 "dev": true,
994 "license": "Apache-2.0"
995 },
996 "node_modules/shuffled-priority-queue": {
997 "version": "2.1.0",
998 "resolved": "https://registry.npmjs.org/shuffled-priority-queue/-/shuffled-priority-queue-2.1.0.tgz",
999 "integrity": "sha512-xhdh7fHyMsr0m/w2kDfRJuBFRS96b9l8ZPNWGaQ+PMvnUnZ/Eh+gJJ9NsHBd7P9k0399WYlCLzsy18EaMfyadA==",
1000 "dev": true,
1001 "license": "MIT",
1002 "dependencies": {
1003 "unordered-set": "^2.0.1"
1004 }
1005 },
1006 "node_modules/signal-promise": {
1007 "version": "1.0.3",
1008 "resolved": "https://registry.npmjs.org/signal-promise/-/signal-promise-1.0.3.tgz",
1009 "integrity": "sha512-WBgv0UnIq2C+Aeh0/n+IRpP6967eIx9WpynTUoiW3isPpfe1zu2LJzyfXdo9Tgef8yR/sGjcMvoUXD7EYdiz+g==",
1010 "dev": true,
1011 "license": "MIT"
1012 },
1013 "node_modules/simdle-native": {
1014 "version": "1.3.9",
1015 "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.9.tgz",
1016 "integrity": "sha512-Isc8sP4OiiIU0mpslD4GHEnR0VQWvR/54WN7YtwEDkNdTJVWtpmvsSvsgRlw5BNGxdYXlVRegdnrSu10H/PhvA==",
1017 "dev": true,
1018 "license": "Apache-2.0",
1019 "optional": true,
1020 "dependencies": {
1021 "b4a": "^1.6.0",
1022 "require-addon": "^1.1.0"
1023 }
1024 },
1025 "node_modules/simdle-universal": {
1026 "version": "1.1.2",
1027 "resolved": "https://registry.npmjs.org/simdle-universal/-/simdle-universal-1.1.2.tgz",
1028 "integrity": "sha512-3n3w1bs+uwgHKQjt6arez83EywNlhZzYvNOhvAASTl/8KqNIcqr6aHyGt3JRlfuUC7iB0tomJRPlJ2cRGIpBzA==",
1029 "dev": true,
1030 "license": "ISC",
1031 "dependencies": {
1032 "b4a": "^1.6.0"
1033 },
1034 "optionalDependencies": {
1035 "simdle-native": "^1.1.1"
1036 }
1037 },
1038 "node_modules/sodium-native": {
1039 "version": "5.1.0",
1040 "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-5.1.0.tgz",
1041 "integrity": "sha512-3RxgyWyJlhTsABPnJVpCI5CoTDANZTqqFrEPqr+kjfnRaBihpVtMUE3yTF40ukdoB1APXeoBNKF3MzZAIHg39g==",
1042 "dev": true,
1043 "license": "MIT",
1044 "dependencies": {
1045 "bare-assert": "^1.2.0",
1046 "require-addon": "^1.1.0",
1047 "which-runtime": "^1.2.1"
1048 },
1049 "engines": {
1050 "bare": ">=1.16.0"
1051 }
1052 },
1053 "node_modules/sodium-secretstream": {
1054 "version": "1.2.0",
1055 "resolved": "https://registry.npmjs.org/sodium-secretstream/-/sodium-secretstream-1.2.0.tgz",
1056 "integrity": "sha512-q/DbraNFXm1KfCiiZvapmz5UC3OlpirYFIvBK2MhGaOFSb3gRyk8OXTi17UI9SGfshQNCpsVvlopogbzZNyW6Q==",
1057 "dev": true,
1058 "license": "MIT",
1059 "dependencies": {
1060 "b4a": "^1.1.1",
1061 "sodium-universal": "^5.0.0"
1062 }
1063 },
1064 "node_modules/sodium-universal": {
1065 "version": "5.0.1",
1066 "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-5.0.1.tgz",
1067 "integrity": "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q==",
1068 "dev": true,
1069 "license": "MIT",
1070 "dependencies": {
1071 "sodium-native": "^5.0.1"
1072 },
1073 "peerDependencies": {
1074 "sodium-javascript": "~0.8.0"
1075 },
1076 "peerDependenciesMeta": {
1077 "sodium-javascript": {
1078 "optional": true
1079 }
1080 }
1081 },
1082 "node_modules/streamx": {
1083 "version": "2.28.0",
1084 "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.0.tgz",
1085 "integrity": "sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==",
1086 "dev": true,
1087 "license": "MIT",
1088 "dependencies": {
1089 "events-universal": "^1.0.0",
1090 "fast-fifo": "^1.3.2",
1091 "text-decoder": "^1.1.0"
1092 }
1093 },
1094 "node_modules/teex": {
1095 "version": "1.0.1",
1096 "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
1097 "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
1098 "dev": true,
1099 "license": "MIT",
1100 "dependencies": {
1101 "streamx": "^2.12.5"
1102 }
1103 },
1104 "node_modules/text-decoder": {
1105 "version": "1.2.7",
1106 "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
1107 "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",
1108 "dev": true,
1109 "license": "Apache-2.0",
1110 "dependencies": {
1111 "b4a": "^1.6.4"
1112 }
1113 },
1114 "node_modules/time-ordered-set": {
1115 "version": "2.0.1",
1116 "resolved": "https://registry.npmjs.org/time-ordered-set/-/time-ordered-set-2.0.1.tgz",
1117 "integrity": "sha512-VJEKmgSN2UiOLB8BpN8Sh2b9LGMHTP5OPrQRpnKjvOheOyzk0mufbjzjKTIG2gO4A+Y+vDJ+0TcLbpUmMLsg8A==",
1118 "dev": true,
1119 "license": "MIT"
1120 },
1121 "node_modules/timeout-refresh": {
1122 "version": "2.0.1",
1123 "resolved": "https://registry.npmjs.org/timeout-refresh/-/timeout-refresh-2.0.1.tgz",
1124 "integrity": "sha512-SVqEcMZBsZF9mA78rjzCrYrUs37LMJk3ShZ851ygZYW1cMeIjs9mL57KO6Iv5mmjSQnOe/29/VAfGXo+oRCiVw==",
1125 "dev": true,
1126 "license": "MIT"
1127 },
1128 "node_modules/udx-native": {
1129 "version": "1.20.7",
1130 "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.20.7.tgz",
1131 "integrity": "sha512-FNG0QpnSt0us2xbLP5mmG5Q0UKdLYjKHuh2eR9VrJSFmoZMzeszYLLhK12+iq5x3eq/rgoGG/lLwPn7IDAr6pg==",
1132 "dev": true,
1133 "license": "Apache-2.0",
1134 "dependencies": {
1135 "b4a": "^1.5.0",
1136 "bare-events": "^2.2.0",
1137 "require-addon": "^1.1.0",
1138 "streamx": "^2.22.0"
1139 },
1140 "engines": {
1141 "bare": ">=1.17.4"
1142 }
1143 },
1144 "node_modules/unordered-set": {
1145 "version": "2.0.1",
1146 "resolved": "https://registry.npmjs.org/unordered-set/-/unordered-set-2.0.1.tgz",
1147 "integrity": "sha512-eUmNTPzdx+q/WvOHW0bgGYLWvWHNT3PTKEQLg0MAQhc0AHASHVHoP/9YytYd4RBVariqno/mEUhVZN98CmD7bg==",
1148 "dev": true,
1149 "license": "MIT"
1150 },
1151 "node_modules/unslab": {
1152 "version": "1.3.0",
1153 "resolved": "https://registry.npmjs.org/unslab/-/unslab-1.3.0.tgz",
1154 "integrity": "sha512-YATkfKAFj47kTzmiQrWXMyRvaVrHsW6MEALa4bm+FhiA2YG4oira+Z3DXN6LrYOYn2Y8eO94Lwl9DOHjs1FpoQ==",
1155 "license": "Apache-2.0",
1156 "dependencies": {
1157 "b4a": "^1.6.6"
1158 }
1159 },
1160 "node_modules/which-runtime": {
1161 "version": "1.4.0",
1162 "resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.4.0.tgz",
1163 "integrity": "sha512-0ugbP4CJW4e2D20jvEcC4973dCgIaHI4Rw1PT+26U9zEve7FyYdWAIwUnoeOYvoCfn+wXHoHTKb1KhkYlb60Pw==",
1164 "dev": true,
1165 "license": "Apache-2.0"
1166 },
1167 "node_modules/xache": {
1168 "version": "1.2.1",
1169 "resolved": "https://registry.npmjs.org/xache/-/xache-1.2.1.tgz",
1170 "integrity": "sha512-igRS6jPreJ54ABdzhh4mCDXcz+XMaWO2q1ABRV2yWYuk29jlp8VT7UBdCqNkX7rpYBbXsebVVKkwIuYZjyZNqA==",
1171 "dev": true,
1172 "license": "MIT"
1173 },
1174 "node_modules/z32": {
1175 "version": "1.1.0",
1176 "resolved": "https://registry.npmjs.org/z32/-/z32-1.1.0.tgz",
1177 "integrity": "sha512-1WUHy+VS6d0HPNspDxvLssBbeQjXMjSnpv0vH82vRAUfg847NmX3OXozp/hRP5jPhxBbrVzrgvAt+UsGNzRFQQ==",
1178 "dev": true,
1179 "license": "MIT",
1180 "dependencies": {
1181 "b4a": "^1.5.3"
1182 }
1183 }
1184 }
1185}
package.json +25 -0
……@@ -0,0 +1,25 @@
1{
2 "name": "atproto-did-peer",
3 "version": "0.1.0",
4 "description": "Keyless, direction-free P2P reader/seeder for an atproto DID's repo+firehose Hypercores: announce-push discovery + event-driven head reconciliation + a keyless read surface. The shared primitive beneath atproto-bridge, atproto-relay and favela (extracted from atproto-bridge did-peer.js).",
5 "type": "module",
6 "main": "index.js",
7 "exports": {
8 ".": "./index.js"
9 },
10 "scripts": {
11 "test": "node test/read-live.mjs"
12 },
13 "dependencies": {
14 "atproto-store": "file:../atproto-store",
15 "atproto-repo": "file:../atproto-repo",
16 "b4a": "^1.8.1",
17 "compact-encoding": "^2.19.0",
18 "protomux": "^3.11.0"
19 },
20 "devDependencies": {
21 "atproto-identity": "file:../atproto-identity",
22 "hyperswarm": "^4.11.0",
23 "corestore": "^7.4.0"
24 }
25}
test/read-live.mjs +51 -0
……@@ -0,0 +1,51 @@
1// Live integration: read wj62's repo over the REAL swarm through the DidPeer module — a genuine
2// P2P read (not the keystone spike's HTTP stand-in). Proves the extracted module works standalone.
3// The CONSUMER owns swarm + discovery + verifyKey (as favela will); the module is the reader.
4import { mkdtempSync } from 'node:fs'
5import { tmpdir } from 'node:os'
6import { join } from 'node:path'
7import Hyperswarm from 'hyperswarm'
8import { DidPeer } from '../index.js'
9// Create the Corestore via atproto-store's OWN copy (openCorestore) so RepoStore's instanceof-Corestore
10// check passes — a plain `new Corestore` from a separately-installed corestore is a different class.
11import { openCorestore } from 'atproto-store/lib/corestore.js'
12import { discoveryTopic } from 'atproto-identity/lib/discovery.js'
13import { decodeDidKey } from 'atproto-identity/lib/did-key.js'
14
15const DID = 'did:plc:wj62ebbusln6gxo5azo6ogzo'
16const KNOWN_RKEY = '3mqkrr6bnh222' // a real wj62 post from this session
17
18async function resolveVerifyKey (did) {
19 const res = await fetch(`https://plc.directory/${did}`)
20 if (!res.ok) throw new Error(`PLC ${res.status}`)
21 const doc = await res.json()
22 const vm = (doc.verificationMethod || []).find((m) => m.id && m.id.endsWith('#atproto')) || (doc.verificationMethod || [])[0]
23 return decodeDidKey(`did:key:${vm.publicKeyMultibase}`).pubkey
24}
25
26const verifyKey = await resolveVerifyKey(DID)
27console.log('resolved wj62 verifyKey from PLC (mandatory auth) ✓')
28
29const store = openCorestore(mkdtempSync(join(tmpdir(), 'didpeer-live-')))
30const swarm = new Hyperswarm()
31const peer = new DidPeer(store, { did: DID, verifyKey, onError: (e) => console.error(' [err]', e.stack || e.message) })
32
33swarm.on('connection', (conn) => peer.attach(conn))
34swarm.join(discoveryTopic(DID), { client: true, server: true })
35await swarm.flush()
36console.log('joined discoveryTopic(wj62); replicating over the swarm...')
37
38const head = await peer.ready({ timeout: 45000 })
39if (!head) { console.log('FAIL: no verified head (no peer reachable / replication stalled)'); await swarm.destroy(); process.exit(1) }
40console.log('VERIFIED HEAD:', { rev: head.rev, cid: head.cid.slice(0, 24) + '…' })
41
42console.log('collections:', await peer.collections())
43const rec = await peer.getRecord('app.bsky.feed.post', KNOWN_RKEY)
44console.log('getRecord ->', JSON.stringify(rec?.value?.text || rec).slice(0, 66))
45const list = await peer.listRecords('app.bsky.feed.post')
46console.log('listRecords ->', list.length, 'posts')
47const { carBytes } = await peer.getRepo()
48console.log('getRepo ->', carBytes.length, 'CAR bytes (keyless, DID-key-verified)')
49
50console.log('\nMODULE OK: atproto-did-peer read wj62 over genuine P2P (announce + replicate + read-view).')
51await swarm.destroy(); await peer.close(); await store.close()