web-dc-api 0.1.4 → 0.1.6
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/dist/cjs/index.js +1 -1
- package/dist/dc.min.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/index.d.ts +934 -878
- package/package.json +4 -8
- package/dist/cjs/helia-core-B1Xqha7a.js +0 -1
- package/dist/cjs/helia-core-D8Uv1KjQ.js +0 -1
- package/dist/cjs/polkadot-api-7PhQf3ws.js +0 -1
- package/dist/cjs/polkadot-api-CtrJVWuZ.js +0 -1
- package/dist/esm/chunks/helia-core-BxMqyK2Y.js +0 -1
- package/dist/esm/chunks/helia-core-DMXRpcO-.js +0 -1
- package/dist/esm/chunks/polkadot-api-5Y9Bw8VT.js +0 -1
- package/dist/esm/chunks/polkadot-api-D69Ioun_.js +0 -1
- package/lib/common/blowfish/block.ts +0 -259
- package/lib/common/blowfish/cipher.ts +0 -144
- package/lib/common/blowfish/const.ts +0 -195
- package/lib/common/chain.ts +0 -469
- package/lib/common/commonclient.ts +0 -202
- package/lib/common/constants.ts +0 -55
- package/lib/common/dc-key/ed25519.ts +0 -343
- package/lib/common/dc-key/keyManager.ts +0 -424
- package/lib/common/dcapi.ts +0 -98
- package/lib/common/dcutil.ts +0 -627
- package/lib/common/define.ts +0 -70
- package/lib/common/error.ts +0 -67
- package/lib/common/grpc-dc.ts +0 -104
- package/lib/common/module-system.ts +0 -184
- package/lib/common/service-worker.ts +0 -234
- package/lib/common/types/types.ts +0 -344
- package/lib/dc.ts +0 -701
- package/lib/implements/account/client.ts +0 -185
- package/lib/implements/account/manager.ts +0 -683
- package/lib/implements/aiproxy/client.ts +0 -357
- package/lib/implements/aiproxy/manager.ts +0 -670
- package/lib/implements/cache/client.ts +0 -105
- package/lib/implements/cache/manager.ts +0 -127
- package/lib/implements/comment/client.ts +0 -982
- package/lib/implements/comment/manager.ts +0 -1151
- package/lib/implements/dc/client.ts +0 -51
- package/lib/implements/dc/manager.ts +0 -33
- package/lib/implements/file/client.ts +0 -253
- package/lib/implements/file/file-cache-manager.ts +0 -142
- package/lib/implements/file/manager.ts +0 -1240
- package/lib/implements/file/seekableFileStream.ts +0 -344
- package/lib/implements/file/streamwriter.ts +0 -322
- package/lib/implements/keyvalue/client.ts +0 -376
- package/lib/implements/keyvalue/manager.ts +0 -759
- package/lib/implements/message/client.ts +0 -250
- package/lib/implements/message/manager.ts +0 -215
- package/lib/implements/threaddb/cbor/coding.ts +0 -62
- package/lib/implements/threaddb/cbor/event.ts +0 -336
- package/lib/implements/threaddb/cbor/node.ts +0 -542
- package/lib/implements/threaddb/cbor/record.ts +0 -398
- package/lib/implements/threaddb/common/AsyncMutex.ts +0 -24
- package/lib/implements/threaddb/common/addrinfo.ts +0 -135
- package/lib/implements/threaddb/common/dispatcher.ts +0 -81
- package/lib/implements/threaddb/common/idbstore-adapter.ts +0 -260
- package/lib/implements/threaddb/common/json-patcher.ts +0 -204
- package/lib/implements/threaddb/common/key.ts +0 -290
- package/lib/implements/threaddb/common/level-adapter.ts +0 -235
- package/lib/implements/threaddb/common/lineReader.ts +0 -79
- package/lib/implements/threaddb/common/logstore.ts +0 -215
- package/lib/implements/threaddb/common/transformed-datastore.ts +0 -308
- package/lib/implements/threaddb/core/app.ts +0 -206
- package/lib/implements/threaddb/core/core.ts +0 -230
- package/lib/implements/threaddb/core/db.ts +0 -249
- package/lib/implements/threaddb/core/event.ts +0 -54
- package/lib/implements/threaddb/core/head.ts +0 -89
- package/lib/implements/threaddb/core/identity.ts +0 -171
- package/lib/implements/threaddb/core/logstore.ts +0 -137
- package/lib/implements/threaddb/core/options.ts +0 -14
- package/lib/implements/threaddb/core/record.ts +0 -54
- package/lib/implements/threaddb/db/collection.ts +0 -1910
- package/lib/implements/threaddb/db/db.ts +0 -698
- package/lib/implements/threaddb/db/json2Query.ts +0 -192
- package/lib/implements/threaddb/db/query.ts +0 -524
- package/lib/implements/threaddb/dbclient.ts +0 -543
- package/lib/implements/threaddb/dbmanager.ts +0 -1906
- package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -549
- package/lib/implements/threaddb/lsstoreds/cache.ts +0 -36
- package/lib/implements/threaddb/lsstoreds/cyclic_batch.ts +0 -87
- package/lib/implements/threaddb/lsstoreds/global.ts +0 -151
- package/lib/implements/threaddb/lsstoreds/headbook.ts +0 -373
- package/lib/implements/threaddb/lsstoreds/keybook.ts +0 -297
- package/lib/implements/threaddb/lsstoreds/logstore.ts +0 -29
- package/lib/implements/threaddb/lsstoreds/metadata.ts +0 -223
- package/lib/implements/threaddb/net/define.ts +0 -149
- package/lib/implements/threaddb/net/grpcClient.ts +0 -589
- package/lib/implements/threaddb/net/grpcserver.ts +0 -146
- package/lib/implements/threaddb/net/net.ts +0 -2047
- package/lib/implements/threaddb/pb/lstore.proto +0 -38
- package/lib/implements/threaddb/pb/lstore.ts +0 -393
- package/lib/implements/threaddb/pb/lstore_pb.d.ts +0 -433
- package/lib/implements/threaddb/pb/lstore_pb.js +0 -1085
- package/lib/implements/threaddb/pb/net.proto +0 -194
- package/lib/implements/threaddb/pb/net_pb.d.ts +0 -2349
- package/lib/implements/threaddb/pb/net_pb.js +0 -5525
- package/lib/implements/threaddb/pb/proto-custom-types.ts +0 -212
- package/lib/implements/util/client.ts +0 -72
- package/lib/implements/util/manager.ts +0 -146
- package/lib/implements/wallet/manager.ts +0 -671
- package/lib/index.ts +0 -57
- package/lib/interfaces/DCContext.ts +0 -51
- package/lib/interfaces/aiproxy-interface.ts +0 -145
- package/lib/interfaces/auth-interface.ts +0 -118
- package/lib/interfaces/cache-interface.ts +0 -22
- package/lib/interfaces/client-interface.ts +0 -11
- package/lib/interfaces/comment-interface.ts +0 -167
- package/lib/interfaces/components/news-component.ts +0 -0
- package/lib/interfaces/database-interface.ts +0 -169
- package/lib/interfaces/file-interface.ts +0 -120
- package/lib/interfaces/index.ts +0 -10
- package/lib/interfaces/keyvalue-interface.ts +0 -156
- package/lib/interfaces/message-interface.ts +0 -22
- package/lib/interfaces/util-interface.ts +0 -31
- package/lib/modules/aiproxy-module.ts +0 -246
- package/lib/modules/auth-module.ts +0 -753
- package/lib/modules/cache-module.ts +0 -99
- package/lib/modules/client-module.ts +0 -71
- package/lib/modules/comment-module.ts +0 -429
- package/lib/modules/components/news-components.ts +0 -390
- package/lib/modules/database-module.ts +0 -598
- package/lib/modules/file-module.ts +0 -291
- package/lib/modules/index.ts +0 -13
- package/lib/modules/keyvalue-module.ts +0 -379
- package/lib/modules/message-module.ts +0 -107
- package/lib/modules/util-module.ts +0 -148
- package/lib/polyfills/process-env-browser.ts +0 -1
- package/lib/proto/datasource.ts +0 -93
- package/lib/proto/dcnet.proto +0 -1601
- package/lib/proto/dcnet_proto.d.ts +0 -22857
- package/lib/proto/dcnet_proto.js +0 -55204
- package/lib/proto/dcnet_proto_sparse.js +0 -55166
- package/lib/proto/oidfetch.proto +0 -25
- package/lib/proto/oidfetch_proto.d.ts +0 -585
- package/lib/proto/oidfetch_proto.js +0 -1247
- package/lib/serverless/babel-browser.ts +0 -39
- package/lib/serverless/base_entity.ts +0 -78
- package/lib/serverless/base_repository.ts +0 -414
- package/lib/serverless/browser_schema_extractor.ts +0 -283
- package/lib/serverless/decorator_factory.ts +0 -322
- package/lib/util/BrowserLineReader.ts +0 -73
- package/lib/util/base64.ts +0 -105
- package/lib/util/bcrypt.ts +0 -206
- package/lib/util/curve25519Encryption.ts +0 -418
- package/lib/util/dccrypt.ts +0 -73
- package/lib/util/logger.ts +0 -104
- package/lib/util/utils.ts +0 -289
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import { Datastore, Key,Query } from 'interface-datastore'
|
|
2
|
-
import { SymKey } from '../core/core'
|
|
3
|
-
import { peerIdFromPrivateKey, peerIdFromPublicKey } from '@libp2p/peer-id'
|
|
4
|
-
import { keys } from '@libp2p/crypto'
|
|
5
|
-
import { base32 } from 'multiformats/bases/base32'
|
|
6
|
-
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
7
|
-
import { DumpKeyBook,KeyBook} from '../core/logstore'
|
|
8
|
-
import { ThreadID } from '@textile/threads-id';
|
|
9
|
-
import type { PeerId,PrivateKey,PublicKey } from "@libp2p/interface";
|
|
10
|
-
import {uniqueLogIds,uniqueThreadIds,AllowEmptyRestore,dsLogKey,dsThreadKey } from './global'
|
|
11
|
-
import { SymmetricKey } from '../common/key';
|
|
12
|
-
import { symKeyFromBytes } from '../../../common/dc-key/keyManager';
|
|
13
|
-
import { publicKeyFromRaw ,privateKeyFromRaw} from '@libp2p/crypto/keys'
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// 键路径构建工具
|
|
19
|
-
const KB_BASE = new Key('/thread/keys')
|
|
20
|
-
const PUB_SUFFIX = new Key('/pub')
|
|
21
|
-
const PRIV_SUFFIX = new Key('/priv')
|
|
22
|
-
const READ_SUFFIX = new Key('/read')
|
|
23
|
-
const SERVICE_SUFFIX = new Key('/service')
|
|
24
|
-
|
|
25
|
-
class DsKeyBook implements KeyBook {
|
|
26
|
-
private ds: Datastore
|
|
27
|
-
|
|
28
|
-
constructor(store: Datastore) {
|
|
29
|
-
this.ds = store
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
async pubKey(t: ThreadID, p: PeerId): Promise<PublicKey|undefined> {
|
|
35
|
-
const key = dsLogKey(t, p, KB_BASE).child(PUB_SUFFIX)
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const value = await this.ds.get(key)
|
|
39
|
-
return keys.publicKeyFromRaw(value)
|
|
40
|
-
} catch (err) {
|
|
41
|
-
if ((err as { code?: string }).code === 'ERR_NOT_FOUND') return
|
|
42
|
-
throw new Error(`Error getting public key: ${(err as Error).message}`)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async addPubKey(t: ThreadID, p: PeerId, pk: PublicKey): Promise<void> {
|
|
47
|
-
if (!pk) throw new Error('Public key is null')
|
|
48
|
-
|
|
49
|
-
const peerId = peerIdFromPublicKey(pk)
|
|
50
|
-
if (!peerId.equals(p)) {
|
|
51
|
-
throw new Error("Log ID doesn't match provided public key")
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const value = pk.raw
|
|
55
|
-
const key = dsLogKey(t, p, KB_BASE).child(PUB_SUFFIX)
|
|
56
|
-
await this.ds.put(key, value)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async privKey(t: ThreadID, p: PeerId): Promise<PrivateKey | null> {
|
|
60
|
-
const key = dsLogKey(t, p, KB_BASE).child(PRIV_SUFFIX)
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
const value = await this.ds.get(key)
|
|
64
|
-
return keys.privateKeyFromRaw(value)
|
|
65
|
-
} catch (err) {
|
|
66
|
-
if ((err as { code?: string }).code === 'ERR_NOT_FOUND') return null
|
|
67
|
-
throw new Error(`Error getting private key: ${(err as Error).message}`)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async addPrivKey(t: ThreadID, p: PeerId, sk: PrivateKey): Promise<void> {
|
|
72
|
-
if (!sk) throw new Error('Private key is null')
|
|
73
|
-
|
|
74
|
-
const peerId = await peerIdFromPrivateKey(sk)
|
|
75
|
-
if (!peerId.equals(p)) {
|
|
76
|
-
throw new Error("Peer ID doesn't match private key")
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const value = sk.raw
|
|
80
|
-
const key = dsLogKey(t, p, KB_BASE).child(PRIV_SUFFIX)
|
|
81
|
-
await this.ds.put(key, value)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
async readKey(t: ThreadID): Promise<SymKey|undefined> {
|
|
86
|
-
const key = dsThreadKey(t, KB_BASE).child(READ_SUFFIX)
|
|
87
|
-
try {
|
|
88
|
-
const value = await this.ds.get(key)
|
|
89
|
-
let symkey = await symKeyFromBytes(value)
|
|
90
|
-
return symkey
|
|
91
|
-
} catch (err) {
|
|
92
|
-
if ((err as { code?: string }).code === 'ERR_NOT_FOUND') return
|
|
93
|
-
throw new Error(`Error getting read key: ${(err as Error).message}`)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async addReadKey(t: ThreadID, rk: SymKey): Promise<void> {
|
|
98
|
-
if (!rk) throw new Error('Read key is null')
|
|
99
|
-
const value = rk.raw
|
|
100
|
-
const key = dsThreadKey(t, KB_BASE).child(READ_SUFFIX)
|
|
101
|
-
await this.ds.put(key, value)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async serviceKey(t: ThreadID): Promise<SymKey | undefined> {
|
|
105
|
-
const key = dsThreadKey(t, KB_BASE).child(SERVICE_SUFFIX)
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
const value = await this.ds.get(key)
|
|
109
|
-
const symkey = await symKeyFromBytes(value)
|
|
110
|
-
return symkey
|
|
111
|
-
} catch (err) {
|
|
112
|
-
if ((err as { code?: string }).code === 'ERR_NOT_FOUND') return
|
|
113
|
-
throw new Error(`Error getting service key: ${(err as Error).message}`)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async addServiceKey(t: ThreadID, fk: SymKey): Promise<void> {
|
|
118
|
-
if (!fk) throw new Error('Service key is null')
|
|
119
|
-
const key = dsThreadKey(t, KB_BASE).child(SERVICE_SUFFIX)
|
|
120
|
-
await this.ds.put(key, fk.raw)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async clearKeys(t: ThreadID): Promise<void> {
|
|
124
|
-
return this.clearKeysInternal(dsThreadKey(t, KB_BASE))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async clearLogKeys(t: ThreadID, p: PeerId): Promise<void> {
|
|
128
|
-
const baseKey = dsLogKey(t, p, KB_BASE)
|
|
129
|
-
await this.ds.delete(baseKey.child(PRIV_SUFFIX))
|
|
130
|
-
await this.ds.delete(baseKey.child(PUB_SUFFIX))
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private async clearKeysInternal(prefix: Key): Promise<void> {
|
|
134
|
-
const q: Query = {
|
|
135
|
-
prefix: prefix.toString(),
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
for await (const result of this.ds.query(q)) {
|
|
139
|
-
await this.ds.delete(result.key)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async logsWithKeys(t: ThreadID): Promise<PeerId[]> {
|
|
144
|
-
const threadKey = KB_BASE.child(
|
|
145
|
-
new Key(t.toString())
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
return uniqueLogIds(this.ds,threadKey, result =>
|
|
149
|
-
result.parent().name()
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async threadsFromKeys(): Promise<ThreadID[]> {
|
|
154
|
-
return uniqueThreadIds(this.ds,KB_BASE, result =>
|
|
155
|
-
result.parent().parent().name()
|
|
156
|
-
)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
async dumpKeys(): Promise<DumpKeyBook> {
|
|
161
|
-
const dump: DumpKeyBook = {
|
|
162
|
-
data: {
|
|
163
|
-
public: {},
|
|
164
|
-
private: {},
|
|
165
|
-
read: {},
|
|
166
|
-
service: {}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const q: Query = { prefix: KB_BASE.toString() }
|
|
171
|
-
const results = this.ds.query(q)
|
|
172
|
-
|
|
173
|
-
for await (const entry of results) {
|
|
174
|
-
const key = new Key(entry.key.toString())
|
|
175
|
-
const namespaces = key.list()
|
|
176
|
-
|
|
177
|
-
if (namespaces.length < 4) {
|
|
178
|
-
throw new Error(`Invalid keybook key: ${entry.key}`)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const suffix = `/${namespaces[namespaces.length - 1]}`
|
|
182
|
-
switch (suffix) {
|
|
183
|
-
case PUB_SUFFIX.toString():
|
|
184
|
-
this.processPublicKeyEntry(namespaces, entry.value, dump)
|
|
185
|
-
break
|
|
186
|
-
case PRIV_SUFFIX.toString():
|
|
187
|
-
this.processPrivateKeyEntry(namespaces, entry.value, dump)
|
|
188
|
-
break
|
|
189
|
-
case READ_SUFFIX.toString():
|
|
190
|
-
this.processReadKeyEntry(namespaces, entry.value, dump)
|
|
191
|
-
break
|
|
192
|
-
case SERVICE_SUFFIX.toString():
|
|
193
|
-
this.processServiceKeyEntry(namespaces, entry.value, dump)
|
|
194
|
-
break
|
|
195
|
-
default:
|
|
196
|
-
throw new Error(`Invalid key suffix: ${suffix}`)
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return dump
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private processPublicKeyEntry(namespaces: string[], value: Uint8Array, dump: DumpKeyBook) {
|
|
204
|
-
const [tid, lid] = namespaces.slice(2, 4)
|
|
205
|
-
if (!tid || !lid) {
|
|
206
|
-
throw new Error(`Invalid namespaces for public key: ${namespaces.join('/')}`)
|
|
207
|
-
}
|
|
208
|
-
const pk = publicKeyFromRaw(value)
|
|
209
|
-
if (!dump.data.public[tid]) {
|
|
210
|
-
dump.data.public[tid] = {}
|
|
211
|
-
}
|
|
212
|
-
dump.data.public[tid][lid] = pk
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
private processPrivateKeyEntry(namespaces: string[], value: Uint8Array, dump: DumpKeyBook) {
|
|
217
|
-
const [tid, lid] = namespaces.slice(2, 4)
|
|
218
|
-
if (!tid || !lid) {
|
|
219
|
-
throw new Error(`Invalid namespaces for private key: ${namespaces.join('/')}`)
|
|
220
|
-
}
|
|
221
|
-
const privk = privateKeyFromRaw(value)
|
|
222
|
-
if (!dump.data.private[tid]) {
|
|
223
|
-
dump.data.private[tid] = {}
|
|
224
|
-
}
|
|
225
|
-
dump.data.private[tid][lid] = privk
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
private processReadKeyEntry(namespaces: string[], value: Uint8Array, dump: DumpKeyBook) {
|
|
229
|
-
const [tid] = namespaces.slice(2, 3)
|
|
230
|
-
dump.data.read[tid!] = Buffer.from(value)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
private processServiceKeyEntry(namespaces: string[], value: Uint8Array, dump: DumpKeyBook) {
|
|
234
|
-
const [tid] = namespaces.slice(2, 3)
|
|
235
|
-
if (!tid) {
|
|
236
|
-
throw new Error(`Invalid namespaces for service key: ${namespaces.join('/')}`)
|
|
237
|
-
}
|
|
238
|
-
dump.data.service[tid] = Buffer.from(value)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async restoreKeys(dump: DumpKeyBook): Promise<void> {
|
|
242
|
-
if (
|
|
243
|
-
!AllowEmptyRestore &&
|
|
244
|
-
Object.keys(dump.data.public).length === 0 &&
|
|
245
|
-
Object.keys(dump.data.private).length === 0 &&
|
|
246
|
-
Object.keys(dump.data.read).length === 0 &&
|
|
247
|
-
Object.keys(dump.data.service).length === 0
|
|
248
|
-
) {
|
|
249
|
-
throw new Error('Empty dump data');
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// clear all local keys
|
|
253
|
-
await this.clearKeysInternal(KB_BASE);
|
|
254
|
-
|
|
255
|
-
for (const tid in dump.data.public) {
|
|
256
|
-
for (const lid in dump.data.public[tid]) {
|
|
257
|
-
const pubKey = dump.data.public[tid][lid];
|
|
258
|
-
if (!pubKey) {
|
|
259
|
-
continue
|
|
260
|
-
}
|
|
261
|
-
await this.addPubKey(ThreadID.fromString(tid), peerIdFromPublicKey(pubKey), pubKey);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
for (const tid in dump.data.private) {
|
|
266
|
-
for (const lid in dump.data.private[tid]) {
|
|
267
|
-
const privKey = dump.data.private[tid][lid];
|
|
268
|
-
if (!privKey) {
|
|
269
|
-
continue
|
|
270
|
-
}
|
|
271
|
-
await this.addPrivKey(ThreadID.fromString(tid), peerIdFromPrivateKey(privKey), privKey);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
for (const tid in dump.data.read) {
|
|
276
|
-
const rk = dump.data.read[tid];
|
|
277
|
-
if (!rk) {
|
|
278
|
-
continue
|
|
279
|
-
}
|
|
280
|
-
const key = await symKeyFromBytes(rk);
|
|
281
|
-
await this.addReadKey(ThreadID.fromString(tid), key);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
for (const tid in dump.data.service) {
|
|
285
|
-
const sk = dump.data.service[tid];
|
|
286
|
-
if (!sk) {
|
|
287
|
-
continue
|
|
288
|
-
}
|
|
289
|
-
const key = await symKeyFromBytes(sk);
|
|
290
|
-
await this.addServiceKey(ThreadID.fromString(tid), key);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export async function newKeyBook(store: Datastore): Promise<DsKeyBook> {
|
|
296
|
-
return new DsKeyBook(store)
|
|
297
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Datastore, Key, Query } from 'interface-datastore'
|
|
3
|
-
import {newAddrBook} from './addr_book'
|
|
4
|
-
import {newKeyBook} from './keybook'
|
|
5
|
-
import {newThreadMetadata} from './metadata'
|
|
6
|
-
import {newHeadBook} from './headbook'
|
|
7
|
-
import * as lstore from '../common/logstore'
|
|
8
|
-
import type { PeerId } from "@libp2p/interface";
|
|
9
|
-
import { QueryExt, QueryResult, TxnDatastoreExtended,Transaction } from '../core/db'
|
|
10
|
-
import { peerIdFromString } from "@libp2p/peer-id";
|
|
11
|
-
import { ThreadID } from '@textile/threads-id';
|
|
12
|
-
import { ILogstore} from '../core/logstore' // 假设核心接口定义
|
|
13
|
-
import {AllowEmptyRestore,EmptyEdgeValue,DSOptions,DefaultOpts} from './global'
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// 日志存储创建函数
|
|
17
|
-
export async function newLogstore(
|
|
18
|
-
store: Datastore & { transaction?: any },
|
|
19
|
-
opts: DSOptions
|
|
20
|
-
): Promise<ILogstore> {
|
|
21
|
-
const addrBook = await newAddrBook( store, opts)
|
|
22
|
-
const keyBook = await newKeyBook(store)
|
|
23
|
-
const threadMetadata = newThreadMetadata(store)
|
|
24
|
-
const headBook = newHeadBook(store as TxnDatastoreExtended)
|
|
25
|
-
|
|
26
|
-
return lstore.newLogstore(keyBook, addrBook, headBook, threadMetadata)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { Key, Datastore, Query } from 'interface-datastore'
|
|
2
|
-
import { IThreadMetadata, DumpMetadata, MetadataKey } from '../core/logstore'
|
|
3
|
-
import { ThreadID } from '@textile/threads-id';
|
|
4
|
-
import * as buffer from "buffer/";
|
|
5
|
-
const { Buffer } = buffer;
|
|
6
|
-
|
|
7
|
-
const AllowEmptyRestore = false
|
|
8
|
-
|
|
9
|
-
// 元数据键前缀
|
|
10
|
-
const tmetaBase = new Key('/thread/meta')
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export function newThreadMetadata(ds: Datastore): DsThreadMetadata {
|
|
14
|
-
return new DsThreadMetadata(ds);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class DsThreadMetadata implements IThreadMetadata {
|
|
18
|
-
constructor(private readonly ds: Datastore) {}
|
|
19
|
-
|
|
20
|
-
async getInt64(t: ThreadID, key: string): Promise<number | null> {
|
|
21
|
-
return this.getValue<number>(t, key)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async putInt64(t: ThreadID, key: string, val: number): Promise<void> {
|
|
25
|
-
return this.setValue(t, key, val)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async getString(t: ThreadID, key: string): Promise<string | null> {
|
|
29
|
-
return this.getValue<string>(t, key)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async putString(t: ThreadID, key: string, val: string): Promise<void> {
|
|
33
|
-
return this.setValue(t, key, val)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async getBool(t: ThreadID, key: string): Promise<boolean | null> {
|
|
37
|
-
return this.getValue<boolean>(t, key)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async putBool(t: ThreadID, key: string, val: boolean): Promise<void> {
|
|
41
|
-
return this.setValue(t, key, val)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async getBytes(t: ThreadID, key: string): Promise<Uint8Array | null> {
|
|
45
|
-
const k = this.keyMeta(t, key)
|
|
46
|
-
try {
|
|
47
|
-
const value = await this.ds.get(k)
|
|
48
|
-
return value
|
|
49
|
-
} catch (err:any) {
|
|
50
|
-
if (err.code === 'ERR_NOT_FOUND') return null
|
|
51
|
-
throw new Error(`Error getting metadata: ${err.message}`)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
async putBytes(t: ThreadID, key: string, val: Uint8Array): Promise<void> {
|
|
57
|
-
const k = this.keyMeta(t, key)
|
|
58
|
-
try {
|
|
59
|
-
await this.ds.put(k, val)
|
|
60
|
-
} catch (err:any) {
|
|
61
|
-
throw new Error(`Error setting metadata: ${err.message}`)
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private keyMeta(t: ThreadID, k: string): Key {
|
|
66
|
-
const tKey = t.toString()
|
|
67
|
-
return tmetaBase.child(new Key(tKey)).child(new Key(k))
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private async getValue<T>(t: ThreadID, key: string): Promise<T | null> {
|
|
71
|
-
const k = this.keyMeta(t, key)
|
|
72
|
-
try {
|
|
73
|
-
const value = await this.ds.get(k)
|
|
74
|
-
// For Uint8Array we'll handle it in getBytes method
|
|
75
|
-
return this.decodeValue<T>(value)
|
|
76
|
-
} catch (err:any) {
|
|
77
|
-
if (err.code === 'ERR_NOT_FOUND') return null
|
|
78
|
-
throw new Error(`Error getting metadata: ${err.message}`)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private async setValue(t: ThreadID, key: string, val: any): Promise<void> {
|
|
83
|
-
const k = this.keyMeta(t, key)
|
|
84
|
-
const value = this.encodeValue(val)
|
|
85
|
-
try {
|
|
86
|
-
await this.ds.put(k, value)
|
|
87
|
-
} catch (err:any) {
|
|
88
|
-
throw new Error(`Error setting metadata: ${err.message}`)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async clearMetadata(t: ThreadID): Promise<void> {
|
|
93
|
-
const prefix = tmetaBase.child(new Key(t.toString())).toString()
|
|
94
|
-
return this.clearKeys(prefix)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async dumpMeta(): Promise<DumpMetadata> {
|
|
98
|
-
const dump: DumpMetadata = {
|
|
99
|
-
data: {
|
|
100
|
-
bool: {},
|
|
101
|
-
int64: {},
|
|
102
|
-
string: {},
|
|
103
|
-
bytes: {}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const results = this.ds.query({ prefix: tmetaBase.toString() })
|
|
108
|
-
try {
|
|
109
|
-
for await (const entry of results) {
|
|
110
|
-
const kns = new Key(entry.key.toString()).list()
|
|
111
|
-
if (kns.length < 4) {
|
|
112
|
-
throw new Error(`Bad metabook key: ${entry.key}`)
|
|
113
|
-
}
|
|
114
|
-
const [,, ts, key] = kns
|
|
115
|
-
const tid = this.parseThreadID(ts!)
|
|
116
|
-
const mk: MetadataKey = { t: tid, k: key! }
|
|
117
|
-
|
|
118
|
-
const value = await this.decodeAnyValue(entry.value)
|
|
119
|
-
this.storeDecodedValue(dump, mk, value)
|
|
120
|
-
}
|
|
121
|
-
} catch (err:any) {
|
|
122
|
-
throw new Error(`Error dumping metadata: ${err.message}`)
|
|
123
|
-
}
|
|
124
|
-
return dump
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async restoreMeta(dump: DumpMetadata): Promise<void> {
|
|
128
|
-
const dataLen = Object.keys(dump.data.bool).length + Object.keys(dump.data.int64).length +
|
|
129
|
-
Object.keys(dump.data.string).length + Object.keys(dump.data.bytes).length
|
|
130
|
-
if (!AllowEmptyRestore && dataLen === 0) {
|
|
131
|
-
throw new Error('Empty metadata dump')
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
await this.clearKeys(tmetaBase.toString())
|
|
135
|
-
|
|
136
|
-
const entries = [
|
|
137
|
-
...Object.entries(dump.data.bool),
|
|
138
|
-
...Object.entries(dump.data.int64),
|
|
139
|
-
...Object.entries(dump.data.string),
|
|
140
|
-
...Object.entries(dump.data.bytes),
|
|
141
|
-
]
|
|
142
|
-
|
|
143
|
-
for (const [mkStr, value] of entries) {
|
|
144
|
-
const mk: MetadataKey = JSON.parse(mkStr);
|
|
145
|
-
await this.setValue(mk.t, mk.k, value)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private async clearKeys(prefix: string): Promise<void> {
|
|
150
|
-
const results = this.ds.queryKeys({ prefix })
|
|
151
|
-
try {
|
|
152
|
-
for await (const key of results) {
|
|
153
|
-
await this.ds.delete(key)
|
|
154
|
-
}
|
|
155
|
-
} catch (err:any) {
|
|
156
|
-
throw new Error(`Error clearing keys: ${err.message}`)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
private decodeValue<T>(buf: Uint8Array): T {
|
|
161
|
-
try {
|
|
162
|
-
const decoder = new TextDecoder()
|
|
163
|
-
return JSON.parse(decoder.decode(buf)) as T
|
|
164
|
-
} catch (err:any) {
|
|
165
|
-
throw new Error(`Value decoding failed: ${err.message}`)
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private encodeValue(val: any): Uint8Array {
|
|
170
|
-
try {
|
|
171
|
-
const encoder = new TextEncoder()
|
|
172
|
-
return encoder.encode(JSON.stringify(val))
|
|
173
|
-
} catch (err:any) {
|
|
174
|
-
throw new Error(`Value encoding failed: ${err.message}`)
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private parseThreadID(ts: string): ThreadID {
|
|
179
|
-
try {
|
|
180
|
-
return ThreadID.fromString(ts)
|
|
181
|
-
} catch (err:any) {
|
|
182
|
-
throw new Error(`Invalid thread ID: ${ts}`)
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
private storeDecodedValue(
|
|
187
|
-
dump: DumpMetadata,
|
|
188
|
-
mk: MetadataKey,
|
|
189
|
-
value: any
|
|
190
|
-
) {
|
|
191
|
-
switch (typeof value) {
|
|
192
|
-
case 'boolean':
|
|
193
|
-
dump.data.bool[mk.t.toString()] = dump.data.bool[mk.t.toString()] || {};
|
|
194
|
-
dump.data.bool[mk.t.toString()]![mk.k] = value;
|
|
195
|
-
break
|
|
196
|
-
case 'number':
|
|
197
|
-
dump.data.int64[mk.t.toString()] = dump.data.int64[mk.t.toString()] || {};
|
|
198
|
-
dump.data.int64[mk.t.toString()]![mk.k] = value;
|
|
199
|
-
break
|
|
200
|
-
case 'string':
|
|
201
|
-
dump.data.string[mk.t.toString()] = dump.data.string[mk.t.toString()] || {};
|
|
202
|
-
dump.data.string[mk.t.toString()]![mk.k] = value;
|
|
203
|
-
break
|
|
204
|
-
default:
|
|
205
|
-
if (value instanceof Uint8Array) {
|
|
206
|
-
// dump.data.bytes[mk.t.toString()] = dump.data.bytes[mk.t.toString()] || '';
|
|
207
|
-
dump.data.bytes[mk.t.toString()] = dump.data.bytes[mk.t.toString()] || {};
|
|
208
|
-
dump.data.bytes[mk.t.toString()]![mk.k] = value;
|
|
209
|
-
} else {
|
|
210
|
-
throw new Error(`Unsupported value type for key: ${mk.k}`)
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
private async decodeAnyValue(buf: Uint8Array): Promise<any> {
|
|
216
|
-
try {
|
|
217
|
-
return this.decodeValue<any>(buf)
|
|
218
|
-
} catch {
|
|
219
|
-
// 原始字节回退
|
|
220
|
-
return buf
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { IRecord,IThreadRecord } from '../core/record';
|
|
2
|
-
import { ThreadID } from '@textile/threads-id';
|
|
3
|
-
import type { PeerId } from '@libp2p/interface';
|
|
4
|
-
import { registry } from '@multiformats/multiaddr';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const netPullingLimit = 1000; // 拉取记录数的限制
|
|
8
|
-
|
|
9
|
-
declare type IProtocol = {
|
|
10
|
-
code: number;
|
|
11
|
-
size: number;
|
|
12
|
-
name: string;
|
|
13
|
-
resolvable: boolean | undefined;
|
|
14
|
-
path: boolean | undefined;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
// 协议常量定义
|
|
18
|
-
export const Protocol = {
|
|
19
|
-
code: 406, // 根据实际协议代码调整
|
|
20
|
-
name: 'thread', // 协议名称
|
|
21
|
-
version: "0.0.1",
|
|
22
|
-
resolvable: false,
|
|
23
|
-
path: false,
|
|
24
|
-
size:-1
|
|
25
|
-
}
|
|
26
|
-
const V = -1
|
|
27
|
-
export const table: Array<[number, number, string, boolean?, boolean?]> = [
|
|
28
|
-
[4, 32, 'ip4'],
|
|
29
|
-
[6, 16, 'tcp'],
|
|
30
|
-
[33, 16, 'dccp'],
|
|
31
|
-
[41, 128, 'ip6'],
|
|
32
|
-
[42, V, 'ip6zone'],
|
|
33
|
-
[43, 8, 'ipcidr'],
|
|
34
|
-
[53, V, 'dns', true],
|
|
35
|
-
[54, V, 'dns4', true],
|
|
36
|
-
[55, V, 'dns6', true],
|
|
37
|
-
[56, V, 'dnsaddr', true],
|
|
38
|
-
[132, 16, 'sctp'],
|
|
39
|
-
[273, 16, 'udp'],
|
|
40
|
-
[275, 0, 'p2p-webrtc-star'],
|
|
41
|
-
[276, 0, 'p2p-webrtc-direct'],
|
|
42
|
-
[277, 0, 'p2p-stardust'],
|
|
43
|
-
[280, 0, 'webrtc-direct'],
|
|
44
|
-
[281, 0, 'webrtc'],
|
|
45
|
-
[290, 0, 'p2p-circuit'],
|
|
46
|
-
[301, 0, 'udt'],
|
|
47
|
-
[302, 0, 'utp'],
|
|
48
|
-
[400, V, 'unix', false, true],
|
|
49
|
-
// `ipfs` is added before `p2p` for legacy support.
|
|
50
|
-
// All text representations will default to `p2p`, but `ipfs` will
|
|
51
|
-
// still be supported
|
|
52
|
-
[421, V, 'ipfs'],
|
|
53
|
-
// `p2p` is the preferred name for 421, and is now the default
|
|
54
|
-
[421, V, 'p2p'],
|
|
55
|
-
[443, 0, 'https'],
|
|
56
|
-
[444, 96, 'onion'],
|
|
57
|
-
[445, 296, 'onion3'],
|
|
58
|
-
[446, V, 'garlic64'],
|
|
59
|
-
[448, 0, 'tls'],
|
|
60
|
-
[449, V, 'sni'],
|
|
61
|
-
[460, 0, 'quic'],
|
|
62
|
-
[461, 0, 'quic-v1'],
|
|
63
|
-
[465, 0, 'webtransport'],
|
|
64
|
-
[466, V, 'certhash'],
|
|
65
|
-
[477, 0, 'ws'],
|
|
66
|
-
[478, 0, 'wss'],
|
|
67
|
-
[479, 0, 'p2p-websocket-star'],
|
|
68
|
-
[480, 0, 'http'],
|
|
69
|
-
[481, V, 'http-path'],
|
|
70
|
-
[777, V, 'memory']
|
|
71
|
-
]
|
|
72
|
-
function createProtocol (code: number, size: number, name: string, resolvable?: any, path?: any): IProtocol {
|
|
73
|
-
return {
|
|
74
|
-
code,
|
|
75
|
-
size,
|
|
76
|
-
name,
|
|
77
|
-
resolvable: Boolean(resolvable),
|
|
78
|
-
path: Boolean(path)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// populate tables
|
|
82
|
-
table.forEach(row => {
|
|
83
|
-
const proto = createProtocol(...row)
|
|
84
|
-
try {
|
|
85
|
-
// 检查协议是否已存在
|
|
86
|
-
const existingProto = registry.getProtocol(proto.code)
|
|
87
|
-
if (!existingProto) {
|
|
88
|
-
registry.addProtocol(proto)
|
|
89
|
-
}
|
|
90
|
-
} catch (error) {
|
|
91
|
-
// 如果协议不存在,添加新协议
|
|
92
|
-
registry.addProtocol(proto)
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
// 添加自定义协议
|
|
96
|
-
try {
|
|
97
|
-
const existingCustomProto = registry.getProtocol(Protocol.code)
|
|
98
|
-
if (!existingCustomProto) {
|
|
99
|
-
registry.addProtocol(Protocol)
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
registry.addProtocol(Protocol)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Records with counters from a peer
|
|
109
|
-
*/
|
|
110
|
-
export interface PeerRecords {
|
|
111
|
-
records: IRecord[];
|
|
112
|
-
counter: number;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Record with timestamp for sorting
|
|
117
|
-
*/
|
|
118
|
-
export interface TimestampedRecord {
|
|
119
|
-
record: IRecord;
|
|
120
|
-
counter: number;
|
|
121
|
-
createtime: BigInt;
|
|
122
|
-
logid: PeerId;
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Record implements IThreadRecord
|
|
129
|
-
*/
|
|
130
|
-
export class ThreadRecord implements IThreadRecord {
|
|
131
|
-
constructor(
|
|
132
|
-
private record: IRecord,
|
|
133
|
-
private _threadID: ThreadID,
|
|
134
|
-
private _logID: PeerId
|
|
135
|
-
) {}
|
|
136
|
-
|
|
137
|
-
value(): IRecord {
|
|
138
|
-
return this.record;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
threadID(): ThreadID {
|
|
142
|
-
return this._threadID;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
logID(): PeerId {
|
|
146
|
-
return this._logID;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|