web-dc-api 0.1.5 → 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,424 +0,0 @@
|
|
|
1
|
-
import { generateMnemonic, mnemonicToSeed, validateMnemonic,mnemonicToEntropy as bip39MnemonicToEntropy } from '@scure/bip39'
|
|
2
|
-
import { wordlist } from '@scure/bip39/wordlists/english'
|
|
3
|
-
|
|
4
|
-
import { ed25519 } from '@noble/curves/ed25519'
|
|
5
|
-
import { sha512 } from '@noble/hashes/sha512'
|
|
6
|
-
import { HDKey } from '@scure/bip32'
|
|
7
|
-
import { Ed25519PrivKey } from './ed25519'
|
|
8
|
-
import * as bcrypt from "../../util/bcrypt"; //
|
|
9
|
-
import { SymKey } from "../../implements/threaddb/core/core";
|
|
10
|
-
import { multiaddr } from "@multiformats/multiaddr";
|
|
11
|
-
import { peerIdFromString } from "@libp2p/peer-id";
|
|
12
|
-
import { Ed25519PubKey } from "./ed25519";
|
|
13
|
-
import type { Multiaddr } from "@multiformats/multiaddr";
|
|
14
|
-
import { sha256 } from "../../util/utils";
|
|
15
|
-
import type { PeerId } from "@libp2p/interface";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* bcrypt 的成本因子
|
|
19
|
-
*/
|
|
20
|
-
const BCRYPT_COST = 12;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export const DERIVATION_PATHS = {
|
|
25
|
-
ETHEREUM: "m/44'/60'/0'/0/0",
|
|
26
|
-
BITCOIN: "m/44'/0'/0'/0/0",
|
|
27
|
-
FILECOIN: "m/44'/461'/0'/0/0",
|
|
28
|
-
POLKADOT: "m/44'/354'/0'/0'/0'",
|
|
29
|
-
SOLANA: "m/44'/501'/0'/0'",
|
|
30
|
-
COSMOS: "m/44'/118'/0'/0/0"
|
|
31
|
-
} as const
|
|
32
|
-
|
|
33
|
-
type ChainType = keyof typeof DERIVATION_PATHS
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export class KeyManager {
|
|
38
|
-
static readonly SEED_SIZE = 32
|
|
39
|
-
static readonly PRIVATE_KEY_SIZE = 64
|
|
40
|
-
static readonly PUBLIC_KEY_SIZE = 32
|
|
41
|
-
// Schnorrkel 常量
|
|
42
|
-
private static readonly SCHNORRKEL_SEED_PREFIX = 'mnemonic'
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// MnemonicToEntropy 将助记词转换为熵
|
|
46
|
-
// 如果助记词无效,则抛出错误
|
|
47
|
-
mnemonicToEntropy(mnemonic: string): Uint8Array {
|
|
48
|
-
// 验证助记词的有效性,传入英文单词表
|
|
49
|
-
if (!validateMnemonic(mnemonic, wordlist)) {
|
|
50
|
-
throw new Error('无效的助记词');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// 使用 @scure/bip39 将助记词转换为熵的 Uint8Array,传入英文单词表
|
|
54
|
-
const entropy = bip39MnemonicToEntropy(mnemonic, wordlist);
|
|
55
|
-
|
|
56
|
-
return entropy;
|
|
57
|
-
}
|
|
58
|
-
// SeedFromMnemonic 从 BIP39 助记词和密码生成 64 字节的种子
|
|
59
|
-
async seedFromMnemonic(mnemonic: string, password: string): Promise<Uint8Array> {
|
|
60
|
-
// 将助记词转换为熵
|
|
61
|
-
const entropy = this.mnemonicToEntropy(mnemonic);
|
|
62
|
-
|
|
63
|
-
// 验证熵的长度:必须在 16 到 32 字节之间,并且是 4 的倍数
|
|
64
|
-
if (entropy.length < 16 || entropy.length > 32 || entropy.length % 4 !== 0) {
|
|
65
|
-
throw new Error("无效的熵长度");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// 准备盐值:"mnemonic" + password
|
|
69
|
-
const saltStr = KeyManager.SCHNORRKEL_SEED_PREFIX + password;
|
|
70
|
-
const encoder = new TextEncoder();
|
|
71
|
-
const salt = encoder.encode(saltStr);
|
|
72
|
-
|
|
73
|
-
// 使用 Web Crypto API 导入熵作为 PBKDF2 的密钥
|
|
74
|
-
const key = await crypto.subtle.importKey(
|
|
75
|
-
'raw',
|
|
76
|
-
entropy,
|
|
77
|
-
{ name: 'PBKDF2' },
|
|
78
|
-
false,
|
|
79
|
-
['deriveBits']
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
// 使用 PBKDF2 生成 64 字节(512 位)的种子,迭代次数为 2048,使用 SHA-512 哈希算法
|
|
83
|
-
const derivedBits = await crypto.subtle.deriveBits(
|
|
84
|
-
{
|
|
85
|
-
name: 'PBKDF2',
|
|
86
|
-
salt: salt,
|
|
87
|
-
iterations: 2048,
|
|
88
|
-
hash: 'SHA-512',
|
|
89
|
-
},
|
|
90
|
-
key,
|
|
91
|
-
64 * 8 // 64 字节 = 512 位
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
// 将导出的位转换为 Uint8Array
|
|
95
|
-
const derivedBytes = new Uint8Array(derivedBits);
|
|
96
|
-
|
|
97
|
-
return derivedBytes;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
async getEd25519KeyFromMnemonic(
|
|
103
|
-
mnemonic: string,
|
|
104
|
-
password: string = ''
|
|
105
|
-
): Promise<Ed25519PrivKey> {
|
|
106
|
-
// 使用兼容 Schnorrkel 的方式生成种子
|
|
107
|
-
const seed = await this.seedFromMnemonic(mnemonic, password)
|
|
108
|
-
const ed25519Key = this.newKeyFromSeed(seed.slice(0, 32))
|
|
109
|
-
const privateKey = new Ed25519PrivKey(ed25519Key.privateKey)
|
|
110
|
-
// 安全清除内存中的敏感数据
|
|
111
|
-
KeyManager.clearSensitiveData(seed)
|
|
112
|
-
KeyManager.clearSensitiveData(ed25519Key.privateKey)
|
|
113
|
-
return privateKey
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
newKeyFromSeed(seed: Uint8Array): {
|
|
119
|
-
privateKey: Uint8Array,
|
|
120
|
-
publicKey: Uint8Array
|
|
121
|
-
} {
|
|
122
|
-
if (seed.length !== KeyManager.SEED_SIZE) {
|
|
123
|
-
throw new Error(`ed25519: bad seed length: ${seed.length}`)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// 1. 计算种子的 SHA-512 哈希
|
|
127
|
-
const h = sha512(seed)
|
|
128
|
-
|
|
129
|
-
// 2. 对前32字节进行clamping(与Go实现一致)
|
|
130
|
-
const h0 = h.slice(0, 32)
|
|
131
|
-
h0[0]! &= 248
|
|
132
|
-
h0[31]! &= 127
|
|
133
|
-
h0[31]! |= 64
|
|
134
|
-
|
|
135
|
-
// 3. 生成公钥
|
|
136
|
-
const publicKey = ed25519.getPublicKey(seed)
|
|
137
|
-
|
|
138
|
-
// 4. 构造64字节私钥(种子 + 公钥)
|
|
139
|
-
const privateKey = new Uint8Array(KeyManager.PRIVATE_KEY_SIZE)
|
|
140
|
-
privateKey.set(seed) // 前32字节是种子
|
|
141
|
-
privateKey.set(publicKey, 32) // 后32字节是公钥
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
privateKey,
|
|
145
|
-
publicKey
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 生成新的助记词
|
|
150
|
-
static generateMnemonic(strength: 128 | 256 = 256): string {
|
|
151
|
-
// strength: 128 生成12个词, 256生成24个词
|
|
152
|
-
return generateMnemonic(wordlist, strength)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// 验证助记词
|
|
156
|
-
static validateMnemonic(mnemonic: string): boolean {
|
|
157
|
-
return validateMnemonic(mnemonic, wordlist)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// 原始的 HD 钱包方式
|
|
162
|
-
static async getMasterKeyFromMnemonic(
|
|
163
|
-
mnemonic: string,
|
|
164
|
-
password: string = ''
|
|
165
|
-
): Promise<HDKey> {
|
|
166
|
-
if (!this.validateMnemonic(mnemonic)) {
|
|
167
|
-
throw new Error('Invalid mnemonic')
|
|
168
|
-
}
|
|
169
|
-
const seed = await mnemonicToSeed(mnemonic, password)
|
|
170
|
-
return HDKey.fromMasterSeed(seed)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
// 派生特定路径的密钥
|
|
176
|
-
static async deriveKey(
|
|
177
|
-
mnemonic: string,
|
|
178
|
-
path: string = "m/44'/60'/0'/0/0", // 以太坊路径
|
|
179
|
-
password: string = ''
|
|
180
|
-
): Promise<{
|
|
181
|
-
privateKey: Uint8Array,
|
|
182
|
-
publicKey: Uint8Array
|
|
183
|
-
}> {
|
|
184
|
-
const masterKey = await this.getMasterKeyFromMnemonic(mnemonic, password)
|
|
185
|
-
const derivedKey = masterKey.derive(path)
|
|
186
|
-
|
|
187
|
-
if (!derivedKey.privateKey || !derivedKey.publicKey) {
|
|
188
|
-
throw new Error('Failed to derive key')
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return {
|
|
192
|
-
privateKey: derivedKey.privateKey,
|
|
193
|
-
publicKey: derivedKey.publicKey
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
static async deriveKeyForChain(
|
|
198
|
-
mnemonic: string,
|
|
199
|
-
chain: ChainType,
|
|
200
|
-
password: string = ''
|
|
201
|
-
) {
|
|
202
|
-
return await this.deriveKey(
|
|
203
|
-
mnemonic,
|
|
204
|
-
DERIVATION_PATHS[chain],
|
|
205
|
-
password
|
|
206
|
-
)
|
|
207
|
-
}
|
|
208
|
-
// 安全清除数据
|
|
209
|
-
private static clearSensitiveData(data: Uint8Array): void {
|
|
210
|
-
data.fill(0)
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* 从 PeerId 中提取公钥 ,只支持 Ed25519PubKey
|
|
221
|
-
* @param peerId libp2p PeerId 实例
|
|
222
|
-
* @returns 提取的公钥
|
|
223
|
-
*/
|
|
224
|
-
export async function extractPublicKeyFromPeerId(
|
|
225
|
-
peerId: PeerId
|
|
226
|
-
): Promise<Ed25519PubKey> {
|
|
227
|
-
try {
|
|
228
|
-
if (peerId.type === "Ed25519") {
|
|
229
|
-
if (peerId.publicKey != null) {
|
|
230
|
-
return Ed25519PubKey.formEd25519PublicKey(peerId.publicKey);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
// 如果无法从 PeerId 中直接获取公钥
|
|
234
|
-
throw new Error("Unable to extract public key from PeerId");
|
|
235
|
-
} catch (error: any) {
|
|
236
|
-
throw new Error(`Failed to extract public key: ${error.message}`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* 从 Multiaddr 中提取 PeerId
|
|
242
|
-
* @param addr Multiaddr 实例或字符串
|
|
243
|
-
* @returns PeerId 实例
|
|
244
|
-
*/
|
|
245
|
-
export async function extractPeerIdFromMultiaddr(
|
|
246
|
-
addr: Multiaddr | string
|
|
247
|
-
): Promise<PeerId> {
|
|
248
|
-
try {
|
|
249
|
-
// 确保地址是 Multiaddr 实例
|
|
250
|
-
const multiAddr = typeof addr === "string" ? multiaddr(addr) : addr;
|
|
251
|
-
|
|
252
|
-
// 获取 p2p 或 ipfs 协议的值
|
|
253
|
-
const p2pValue = multiAddr.getPeerId();
|
|
254
|
-
|
|
255
|
-
if (!p2pValue) {
|
|
256
|
-
throw new Error("No PeerId found in multiaddr");
|
|
257
|
-
}
|
|
258
|
-
// 从字符串创建 PeerId
|
|
259
|
-
return peerIdFromString(p2pValue);
|
|
260
|
-
} catch (error: any) {
|
|
261
|
-
throw new Error(`Failed to extract PeerId: ${error.message}`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* 从字节数组生成对称密钥
|
|
269
|
-
* @param bytes - 输入字节数组
|
|
270
|
-
* @returns Promise<SymKey> - 返回对称密钥
|
|
271
|
-
*/
|
|
272
|
-
export async function symKeyFromBytes(bytes: Uint8Array): Promise<SymKey> {
|
|
273
|
-
const key = await window.crypto.subtle.importKey(
|
|
274
|
-
"raw",
|
|
275
|
-
bytes,
|
|
276
|
-
{ name: "AES-GCM" },
|
|
277
|
-
true,
|
|
278
|
-
["encrypt", "decrypt"]
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
return {
|
|
282
|
-
key,
|
|
283
|
-
raw: bytes,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* 生成用户私钥加解密的密钥
|
|
289
|
-
* @param account - 用户账号
|
|
290
|
-
* @param password - 用户密码
|
|
291
|
-
* @returns Promise<SymKey> - 返回对称加密密钥
|
|
292
|
-
*/
|
|
293
|
-
export async function generateSymKeyForPrikey(
|
|
294
|
-
account: string,
|
|
295
|
-
password: string
|
|
296
|
-
): Promise<SymKey> {
|
|
297
|
-
try {
|
|
298
|
-
// 计算密码的 SHA256 哈希
|
|
299
|
-
const passwordHash = await sha256(new TextEncoder().encode(password));
|
|
300
|
-
|
|
301
|
-
// 从哈希中提取盐值(与 Go 代码保持一致,使用后16字节)
|
|
302
|
-
const salt = passwordHash.slice(16, 32);
|
|
303
|
-
|
|
304
|
-
// 使用 bcrypt 生成哈希
|
|
305
|
-
const bcryptHash = await bcrypt.generateFromPasswordWithSalt(
|
|
306
|
-
passwordHash,
|
|
307
|
-
BCRYPT_COST,
|
|
308
|
-
salt
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
const hash = bcryptHash.hash;
|
|
312
|
-
// 将 account 转换为字节数组
|
|
313
|
-
const accountBytes = new TextEncoder().encode(account);
|
|
314
|
-
|
|
315
|
-
// 合并 bcryptHash 和 account 字节
|
|
316
|
-
const combined = new Uint8Array(hash.length + accountBytes.length);
|
|
317
|
-
combined.set(hash);
|
|
318
|
-
combined.set(accountBytes, hash.length);
|
|
319
|
-
|
|
320
|
-
// 计算最终的 SHA256 哈希
|
|
321
|
-
const keyBytes = await sha256(combined);
|
|
322
|
-
|
|
323
|
-
// 从字节生成对称密钥
|
|
324
|
-
return await symKeyFromBytes(keyBytes);
|
|
325
|
-
} catch (error: any) {
|
|
326
|
-
throw new Error(`Failed to generate symmetric key: ${error.message}`);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* 将 Ed25519 公钥转换为 CryptoKey
|
|
333
|
-
* @param publicKey - 输入的公钥(支持多种格式)
|
|
334
|
-
* @param format - 密钥格式(默认自动检测)
|
|
335
|
-
*/
|
|
336
|
-
export async function ed25519PublicKeyToCryptoKey(
|
|
337
|
-
publicKey: Uint8Array | string,
|
|
338
|
-
format: 'raw' | 'spki' = 'raw'
|
|
339
|
-
): Promise<CryptoKey> {
|
|
340
|
-
// 1. 统一转换为 ArrayBuffer
|
|
341
|
-
let keyData: ArrayBuffer;
|
|
342
|
-
if (typeof publicKey === 'string') {
|
|
343
|
-
// 处理 PEM 格式(自动识别 SPKI)
|
|
344
|
-
if (publicKey.startsWith('-----BEGIN')) {
|
|
345
|
-
const pemHeader = '-----BEGIN PUBLIC KEY-----';
|
|
346
|
-
const pemFooter = '-----END PUBLIC KEY-----';
|
|
347
|
-
const pemContents = publicKey
|
|
348
|
-
.replace(pemHeader, '')
|
|
349
|
-
.replace(pemFooter, '')
|
|
350
|
-
.replace(/\s+/g, '');
|
|
351
|
-
keyData = Uint8Array.from(atob(pemContents), c => c.charCodeAt(0)) as any;
|
|
352
|
-
} else {
|
|
353
|
-
// 处理 Base64/Hex 等编码的 RAW 格式
|
|
354
|
-
keyData = Uint8Array.from(atob(publicKey), c => c.charCodeAt(0)) as any;
|
|
355
|
-
}
|
|
356
|
-
} else {
|
|
357
|
-
keyData = publicKey as any;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// 2. 检测密钥格式
|
|
361
|
-
const detectedFormat = format === 'spki' || publicKey instanceof Uint8Array
|
|
362
|
-
? format
|
|
363
|
-
: 'spki';
|
|
364
|
-
|
|
365
|
-
// 3. 导入为 CryptoKey
|
|
366
|
-
return crypto.subtle.importKey(
|
|
367
|
-
detectedFormat,
|
|
368
|
-
keyData,
|
|
369
|
-
{
|
|
370
|
-
name: 'Ed25519',
|
|
371
|
-
namedCurve: 'Ed25519'
|
|
372
|
-
},
|
|
373
|
-
true, // 是否可导出
|
|
374
|
-
['verify'] // 公钥用途
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* 将 Ed25519 私钥转换为 CryptoKey
|
|
381
|
-
* @param privateKey - 输入的私钥(支持多种格式)
|
|
382
|
-
* @param format - 密钥格式(默认自动检测)
|
|
383
|
-
*/
|
|
384
|
-
export async function ed25519PrivateKeyToCryptoKey(
|
|
385
|
-
privateKey: Uint8Array | string,
|
|
386
|
-
format: 'raw' | 'pkcs8' = 'pkcs8'
|
|
387
|
-
): Promise<CryptoKey> {
|
|
388
|
-
// 1. 统一转换为 ArrayBuffer
|
|
389
|
-
let keyData: ArrayBuffer;
|
|
390
|
-
if (typeof privateKey === 'string') {
|
|
391
|
-
// 处理 PEM 格式(自动识别 PKCS8)
|
|
392
|
-
if (privateKey.startsWith('-----BEGIN')) {
|
|
393
|
-
const pemHeader = '-----BEGIN PRIVATE KEY-----';
|
|
394
|
-
const pemFooter = '-----END PRIVATE KEY-----';
|
|
395
|
-
const pemContents = privateKey
|
|
396
|
-
.replace(pemHeader, '')
|
|
397
|
-
.replace(pemFooter, '')
|
|
398
|
-
.replace(/\s+/g, '');
|
|
399
|
-
keyData = Uint8Array.from(atob(pemContents), c => c.charCodeAt(0)) as any;
|
|
400
|
-
} else {
|
|
401
|
-
// 处理 Base64/Hex 编码的 RAW 格式
|
|
402
|
-
keyData = Uint8Array.from(atob(privateKey), c => c.charCodeAt(0)) as any;
|
|
403
|
-
}
|
|
404
|
-
} else {
|
|
405
|
-
keyData = privateKey as any;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// 2. 检测密钥格式
|
|
409
|
-
const detectedFormat = format === 'pkcs8' || privateKey instanceof Uint8Array
|
|
410
|
-
? format
|
|
411
|
-
: 'pkcs8';
|
|
412
|
-
|
|
413
|
-
// 3. 导入为 CryptoKey
|
|
414
|
-
return crypto.subtle.importKey(
|
|
415
|
-
detectedFormat,
|
|
416
|
-
keyData,
|
|
417
|
-
{
|
|
418
|
-
name: 'Ed25519',
|
|
419
|
-
namedCurve: 'Ed25519'
|
|
420
|
-
},
|
|
421
|
-
true,
|
|
422
|
-
['sign']
|
|
423
|
-
);
|
|
424
|
-
}
|
package/lib/common/dcapi.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import type { Libp2p } from "libp2p";
|
|
2
|
-
import type { Multiaddr } from "@multiformats/multiaddr";
|
|
3
|
-
|
|
4
|
-
import { DCGrpcClient } from "./grpc-dc";
|
|
5
|
-
|
|
6
|
-
import { keys } from "@libp2p/crypto";
|
|
7
|
-
import { sha256, getRandomBytes, concatenateUint8Arrays } from "../util/utils";
|
|
8
|
-
import { Blocks } from "helia";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export class Client {
|
|
14
|
-
readonly protocol: string;
|
|
15
|
-
p2pNode: Libp2p;
|
|
16
|
-
blockstore: Blocks;
|
|
17
|
-
peerAddr: Multiaddr;
|
|
18
|
-
token: string;
|
|
19
|
-
|
|
20
|
-
constructor(node: Libp2p,blockstore: Blocks, peerAddr: Multiaddr, protocol: string) {
|
|
21
|
-
this.protocol = protocol;
|
|
22
|
-
this.p2pNode = node;
|
|
23
|
-
this.peerAddr = peerAddr;
|
|
24
|
-
this.token = "";
|
|
25
|
-
this.blockstore = blockstore
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async GetToken(
|
|
29
|
-
appId: string,
|
|
30
|
-
pubkey: string,
|
|
31
|
-
signCallback: (payload: Uint8Array) => Promise<Uint8Array> ,
|
|
32
|
-
peerAddr?: Multiaddr
|
|
33
|
-
): Promise<string> {
|
|
34
|
-
try {
|
|
35
|
-
if (this.p2pNode == null) {
|
|
36
|
-
throw new Error("p2pNode is null");
|
|
37
|
-
}
|
|
38
|
-
if (!peerAddr) {
|
|
39
|
-
peerAddr = this.peerAddr;
|
|
40
|
-
}
|
|
41
|
-
if (!pubkey || pubkey.length == 0) {
|
|
42
|
-
throw new Error("pubkey is empty");
|
|
43
|
-
}
|
|
44
|
-
const grpcClient = new DCGrpcClient(
|
|
45
|
-
this.p2pNode,
|
|
46
|
-
peerAddr,
|
|
47
|
-
this.token,
|
|
48
|
-
this.protocol
|
|
49
|
-
);
|
|
50
|
-
const token = await grpcClient.GetToken(appId, pubkey, signCallback);
|
|
51
|
-
this.token = token;
|
|
52
|
-
return token;
|
|
53
|
-
} catch (err) {
|
|
54
|
-
console.error("GetToken error:", err);
|
|
55
|
-
return "";
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// 清除token
|
|
60
|
-
async ClearToken(): Promise<void> {
|
|
61
|
-
this.token = "";
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// 验证token
|
|
66
|
-
async ValidToken(
|
|
67
|
-
peerAddr?: Multiaddr
|
|
68
|
-
): Promise<void> {
|
|
69
|
-
try {
|
|
70
|
-
if (this.p2pNode == null) {
|
|
71
|
-
throw new Error("p2pNode is null");
|
|
72
|
-
}
|
|
73
|
-
if (!peerAddr) {
|
|
74
|
-
peerAddr = this.peerAddr;
|
|
75
|
-
}
|
|
76
|
-
const grpcClient = new DCGrpcClient(
|
|
77
|
-
this.p2pNode,
|
|
78
|
-
peerAddr,
|
|
79
|
-
this.token,
|
|
80
|
-
this.protocol
|
|
81
|
-
);
|
|
82
|
-
await grpcClient.ValidToken();
|
|
83
|
-
} catch (err) {
|
|
84
|
-
throw err;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// 获取Token
|
|
89
|
-
async refreshToken(
|
|
90
|
-
appId: string,
|
|
91
|
-
pubkey: string,
|
|
92
|
-
signCallback: (payload: Uint8Array) => Promise<Uint8Array>,
|
|
93
|
-
peerAddr?: Multiaddr
|
|
94
|
-
): Promise<string> {
|
|
95
|
-
this.ClearToken();
|
|
96
|
-
return await this.GetToken(appId, pubkey, signCallback, peerAddr);
|
|
97
|
-
}
|
|
98
|
-
}
|