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.
Files changed (148) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/dc.min.js +1 -1
  3. package/dist/esm/index.js +1 -1
  4. package/dist/index.d.ts +934 -878
  5. package/package.json +4 -8
  6. package/dist/cjs/helia-core-B1Xqha7a.js +0 -1
  7. package/dist/cjs/helia-core-D8Uv1KjQ.js +0 -1
  8. package/dist/cjs/polkadot-api-7PhQf3ws.js +0 -1
  9. package/dist/cjs/polkadot-api-CtrJVWuZ.js +0 -1
  10. package/dist/esm/chunks/helia-core-BxMqyK2Y.js +0 -1
  11. package/dist/esm/chunks/helia-core-DMXRpcO-.js +0 -1
  12. package/dist/esm/chunks/polkadot-api-5Y9Bw8VT.js +0 -1
  13. package/dist/esm/chunks/polkadot-api-D69Ioun_.js +0 -1
  14. package/lib/common/blowfish/block.ts +0 -259
  15. package/lib/common/blowfish/cipher.ts +0 -144
  16. package/lib/common/blowfish/const.ts +0 -195
  17. package/lib/common/chain.ts +0 -469
  18. package/lib/common/commonclient.ts +0 -202
  19. package/lib/common/constants.ts +0 -55
  20. package/lib/common/dc-key/ed25519.ts +0 -343
  21. package/lib/common/dc-key/keyManager.ts +0 -424
  22. package/lib/common/dcapi.ts +0 -98
  23. package/lib/common/dcutil.ts +0 -627
  24. package/lib/common/define.ts +0 -70
  25. package/lib/common/error.ts +0 -67
  26. package/lib/common/grpc-dc.ts +0 -104
  27. package/lib/common/module-system.ts +0 -184
  28. package/lib/common/service-worker.ts +0 -234
  29. package/lib/common/types/types.ts +0 -344
  30. package/lib/dc.ts +0 -701
  31. package/lib/implements/account/client.ts +0 -185
  32. package/lib/implements/account/manager.ts +0 -683
  33. package/lib/implements/aiproxy/client.ts +0 -357
  34. package/lib/implements/aiproxy/manager.ts +0 -670
  35. package/lib/implements/cache/client.ts +0 -105
  36. package/lib/implements/cache/manager.ts +0 -127
  37. package/lib/implements/comment/client.ts +0 -982
  38. package/lib/implements/comment/manager.ts +0 -1151
  39. package/lib/implements/dc/client.ts +0 -51
  40. package/lib/implements/dc/manager.ts +0 -33
  41. package/lib/implements/file/client.ts +0 -253
  42. package/lib/implements/file/file-cache-manager.ts +0 -142
  43. package/lib/implements/file/manager.ts +0 -1240
  44. package/lib/implements/file/seekableFileStream.ts +0 -344
  45. package/lib/implements/file/streamwriter.ts +0 -322
  46. package/lib/implements/keyvalue/client.ts +0 -376
  47. package/lib/implements/keyvalue/manager.ts +0 -759
  48. package/lib/implements/message/client.ts +0 -250
  49. package/lib/implements/message/manager.ts +0 -215
  50. package/lib/implements/threaddb/cbor/coding.ts +0 -62
  51. package/lib/implements/threaddb/cbor/event.ts +0 -336
  52. package/lib/implements/threaddb/cbor/node.ts +0 -542
  53. package/lib/implements/threaddb/cbor/record.ts +0 -398
  54. package/lib/implements/threaddb/common/AsyncMutex.ts +0 -24
  55. package/lib/implements/threaddb/common/addrinfo.ts +0 -135
  56. package/lib/implements/threaddb/common/dispatcher.ts +0 -81
  57. package/lib/implements/threaddb/common/idbstore-adapter.ts +0 -260
  58. package/lib/implements/threaddb/common/json-patcher.ts +0 -204
  59. package/lib/implements/threaddb/common/key.ts +0 -290
  60. package/lib/implements/threaddb/common/level-adapter.ts +0 -235
  61. package/lib/implements/threaddb/common/lineReader.ts +0 -79
  62. package/lib/implements/threaddb/common/logstore.ts +0 -215
  63. package/lib/implements/threaddb/common/transformed-datastore.ts +0 -308
  64. package/lib/implements/threaddb/core/app.ts +0 -206
  65. package/lib/implements/threaddb/core/core.ts +0 -230
  66. package/lib/implements/threaddb/core/db.ts +0 -249
  67. package/lib/implements/threaddb/core/event.ts +0 -54
  68. package/lib/implements/threaddb/core/head.ts +0 -89
  69. package/lib/implements/threaddb/core/identity.ts +0 -171
  70. package/lib/implements/threaddb/core/logstore.ts +0 -137
  71. package/lib/implements/threaddb/core/options.ts +0 -14
  72. package/lib/implements/threaddb/core/record.ts +0 -54
  73. package/lib/implements/threaddb/db/collection.ts +0 -1910
  74. package/lib/implements/threaddb/db/db.ts +0 -698
  75. package/lib/implements/threaddb/db/json2Query.ts +0 -192
  76. package/lib/implements/threaddb/db/query.ts +0 -524
  77. package/lib/implements/threaddb/dbclient.ts +0 -543
  78. package/lib/implements/threaddb/dbmanager.ts +0 -1906
  79. package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -549
  80. package/lib/implements/threaddb/lsstoreds/cache.ts +0 -36
  81. package/lib/implements/threaddb/lsstoreds/cyclic_batch.ts +0 -87
  82. package/lib/implements/threaddb/lsstoreds/global.ts +0 -151
  83. package/lib/implements/threaddb/lsstoreds/headbook.ts +0 -373
  84. package/lib/implements/threaddb/lsstoreds/keybook.ts +0 -297
  85. package/lib/implements/threaddb/lsstoreds/logstore.ts +0 -29
  86. package/lib/implements/threaddb/lsstoreds/metadata.ts +0 -223
  87. package/lib/implements/threaddb/net/define.ts +0 -149
  88. package/lib/implements/threaddb/net/grpcClient.ts +0 -589
  89. package/lib/implements/threaddb/net/grpcserver.ts +0 -146
  90. package/lib/implements/threaddb/net/net.ts +0 -2047
  91. package/lib/implements/threaddb/pb/lstore.proto +0 -38
  92. package/lib/implements/threaddb/pb/lstore.ts +0 -393
  93. package/lib/implements/threaddb/pb/lstore_pb.d.ts +0 -433
  94. package/lib/implements/threaddb/pb/lstore_pb.js +0 -1085
  95. package/lib/implements/threaddb/pb/net.proto +0 -194
  96. package/lib/implements/threaddb/pb/net_pb.d.ts +0 -2349
  97. package/lib/implements/threaddb/pb/net_pb.js +0 -5525
  98. package/lib/implements/threaddb/pb/proto-custom-types.ts +0 -212
  99. package/lib/implements/util/client.ts +0 -72
  100. package/lib/implements/util/manager.ts +0 -146
  101. package/lib/implements/wallet/manager.ts +0 -671
  102. package/lib/index.ts +0 -57
  103. package/lib/interfaces/DCContext.ts +0 -51
  104. package/lib/interfaces/aiproxy-interface.ts +0 -145
  105. package/lib/interfaces/auth-interface.ts +0 -118
  106. package/lib/interfaces/cache-interface.ts +0 -22
  107. package/lib/interfaces/client-interface.ts +0 -11
  108. package/lib/interfaces/comment-interface.ts +0 -167
  109. package/lib/interfaces/components/news-component.ts +0 -0
  110. package/lib/interfaces/database-interface.ts +0 -169
  111. package/lib/interfaces/file-interface.ts +0 -120
  112. package/lib/interfaces/index.ts +0 -10
  113. package/lib/interfaces/keyvalue-interface.ts +0 -156
  114. package/lib/interfaces/message-interface.ts +0 -22
  115. package/lib/interfaces/util-interface.ts +0 -31
  116. package/lib/modules/aiproxy-module.ts +0 -246
  117. package/lib/modules/auth-module.ts +0 -753
  118. package/lib/modules/cache-module.ts +0 -99
  119. package/lib/modules/client-module.ts +0 -71
  120. package/lib/modules/comment-module.ts +0 -429
  121. package/lib/modules/components/news-components.ts +0 -390
  122. package/lib/modules/database-module.ts +0 -598
  123. package/lib/modules/file-module.ts +0 -291
  124. package/lib/modules/index.ts +0 -13
  125. package/lib/modules/keyvalue-module.ts +0 -379
  126. package/lib/modules/message-module.ts +0 -107
  127. package/lib/modules/util-module.ts +0 -148
  128. package/lib/polyfills/process-env-browser.ts +0 -1
  129. package/lib/proto/datasource.ts +0 -93
  130. package/lib/proto/dcnet.proto +0 -1601
  131. package/lib/proto/dcnet_proto.d.ts +0 -22857
  132. package/lib/proto/dcnet_proto.js +0 -55204
  133. package/lib/proto/dcnet_proto_sparse.js +0 -55166
  134. package/lib/proto/oidfetch.proto +0 -25
  135. package/lib/proto/oidfetch_proto.d.ts +0 -585
  136. package/lib/proto/oidfetch_proto.js +0 -1247
  137. package/lib/serverless/babel-browser.ts +0 -39
  138. package/lib/serverless/base_entity.ts +0 -78
  139. package/lib/serverless/base_repository.ts +0 -414
  140. package/lib/serverless/browser_schema_extractor.ts +0 -283
  141. package/lib/serverless/decorator_factory.ts +0 -322
  142. package/lib/util/BrowserLineReader.ts +0 -73
  143. package/lib/util/base64.ts +0 -105
  144. package/lib/util/bcrypt.ts +0 -206
  145. package/lib/util/curve25519Encryption.ts +0 -418
  146. package/lib/util/dccrypt.ts +0 -73
  147. package/lib/util/logger.ts +0 -104
  148. package/lib/util/utils.ts +0 -289
@@ -1,683 +0,0 @@
1
- import type { Multiaddr } from "@multiformats/multiaddr";
2
- import { ChainUtil } from "../../common/chain";
3
- import { DcUtil } from "../../common/dcutil";
4
- import { DCConnectInfo, NFTBindStatus, User } from "../../common/types/types";
5
- import { AccountClient } from "./client";
6
- import { sha256, uint32ToLittleEndianBytes } from "../../util/utils";
7
- import { Ed25519PrivKey, Ed25519PubKey } from "../../common/dc-key/ed25519";
8
- import { DCContext } from "../../../lib/interfaces/DCContext";
9
- import { PeerId } from "@libp2p/interface";
10
- import {
11
- extractPublicKeyFromPeerId,
12
- generateSymKeyForPrikey,
13
- KeyManager,
14
- } from "../../common/dc-key/keyManager";
15
- import { SymmetricKey } from "../threaddb/common/key";
16
- import { peerIdFromString } from "@libp2p/peer-id";
17
- import { request } from "http";
18
-
19
- // 错误定义
20
- export class AccountError extends Error {
21
- constructor(message: string) {
22
- super(message);
23
- this.name = "AccountError";
24
- }
25
- }
26
- export const Errors = {
27
- ErrNoDcPeerConnected: new AccountError("no dc peer connected"),
28
- ErrNodeAddrIsNull: new AccountError("nodeAddr is null"),
29
- ErrChainUtilIsNull: new AccountError("chainUtil is null"),
30
- ErrAccountLogin: new AccountError("account login error"),
31
- ErrNoAccountPeerConnected: new AccountError("no account peer connected"),
32
- // account privatekey sign is null
33
- ErrAccountPrivateSignIsNull: new AccountError(
34
- "account privatekey sign is null"
35
- ),
36
- // 公钥唯恐
37
- ErrAccountPublicKeyIsNull: new AccountError("account publickey is null"),
38
- };
39
- export class AccountManager {
40
- dc: DcUtil;
41
- chainUtil: ChainUtil | undefined;
42
- context: DCContext;
43
- constructor(context: DCContext) {
44
- this.dc = context.dcutil;
45
- this.chainUtil = context.dcChain;
46
- this.context = context;
47
- }
48
-
49
- // 获取用户备用节点
50
- getAccountNodeAddr = async (): Promise<[Multiaddr | null, Error | null]> => {
51
- if (!this.context.connectedDc.client) {
52
- console.error("dcClient is null");
53
- return [null, Errors.ErrNoDcPeerConnected];
54
- }
55
- if (!this.chainUtil) {
56
- console.error("chainUtil is null");
57
- return [null, Errors.ErrChainUtilIsNull];
58
- }
59
- if (!this.context) {
60
- console.error("context is null");
61
- return [null, Errors.ErrAccountPrivateSignIsNull];
62
- }
63
- const pubkeyRaw = this.context.getPubkeyRaw();
64
- const peerAddrs = await this.chainUtil.getAccountPeers(pubkeyRaw);
65
- if (peerAddrs && peerAddrs.length > 0) {
66
- // 连接备用节点
67
- const nodeAddr = await this.dc?._connectPeers(peerAddrs);
68
- console.log("_connectNodeAddrs nodeAddr:", nodeAddr);
69
- if (nodeAddr) {
70
- return [nodeAddr, null];
71
- }
72
- }
73
- return [null, Errors.ErrNoAccountPeerConnected];
74
- };
75
- // 获取用户信息
76
- getUserInfoWithNft = async (
77
- nftAccount: string
78
- ): Promise<[User | null, Error | null]> => {
79
- if (!this.context.connectedDc.client) {
80
- console.error("dcClient is null");
81
- return [null, Errors.ErrNoDcPeerConnected];
82
- }
83
- if (!this.chainUtil) {
84
- console.error("chainUtil is null");
85
- return [null, Errors.ErrChainUtilIsNull];
86
- }
87
- // 从链上获取
88
- const userInfo = await this.chainUtil.getUserInfoWithNft(nftAccount);
89
- console.log("userInfo reply:", userInfo);
90
- return [userInfo, null];
91
- };
92
- bindAccessPeerToUser = async (
93
- peerAddr: Multiaddr
94
- ): Promise<[boolean | null, Error | null]> => {
95
- if (!this.context.connectedDc.client) {
96
- console.error("dcClient is null");
97
- return [false, Errors.ErrNoDcPeerConnected];
98
- }
99
- if (!this.chainUtil) {
100
- console.error("chainUtil is null");
101
- return [null, Errors.ErrChainUtilIsNull];
102
- }
103
- if (!this.context) {
104
- console.error("context is null");
105
- return [null, Errors.ErrAccountPrivateSignIsNull];
106
- }
107
- const peerId = peerAddr.getPeerId();
108
- if (!peerId) {
109
- console.error("peerId is null");
110
- return [null, Errors.ErrNoAccountPeerConnected];
111
- }
112
- // 绑定节点
113
- const blockHeight = await this.chainUtil.getBlockHeight();
114
- const accountClient = new AccountClient(this.context.connectedDc.client);
115
- const bindResult = await accountClient.bindAccessPeerToUser(
116
- this.context,
117
- blockHeight ? blockHeight : 0,
118
- peerId.toString()
119
- );
120
- console.log("bindAccessPeerToUser bindResult:", bindResult);
121
- return [true, null];
122
- };
123
-
124
- /**
125
- * 将私钥绑定NFT账号(NFT账号+密码+安全码)
126
- * @param account NFT账号
127
- * @param password 密码
128
- * @param seccode 安全码
129
- * @returns [状态码, 错误信息]
130
- */
131
- async bindNFTAccount(
132
- account: string,
133
- password: string,
134
- seccode: string,
135
- mnemonic: string
136
- ): Promise<[NFTBindStatus, Error | null]> {
137
- // 检查节点连接
138
- if (!this.context.connectedDc.client) {
139
- return [NFTBindStatus.DcPeerNotConnected, Errors.ErrNoDcPeerConnected];
140
- }
141
- if (!this.context.connectedDc.nodeAddr) {
142
- return [NFTBindStatus.DcPeerNotConnected, Errors.ErrNodeAddrIsNull];
143
- }
144
-
145
- try {
146
- const connectedPeerIdStr = this.context.connectedDc.nodeAddr.getPeerId();
147
- if (!connectedPeerIdStr) {
148
- return [NFTBindStatus.DcPeerNotConnected, Errors.ErrNodeAddrIsNull];
149
- }
150
- const connectedPeerId = peerIdFromString(connectedPeerIdStr);
151
- // 生成账户请求
152
- const [req, status] = await this.generateAccountDealRequest(
153
- account,
154
- password,
155
- seccode,
156
- mnemonic,
157
- connectedPeerId
158
- );
159
-
160
- if (status !== NFTBindStatus.Success) {
161
- return [
162
- status,
163
- new AccountError(`Failed to generate account request: ${status}`),
164
- ];
165
- }
166
-
167
- // 获取客户端
168
- const accountClient = new AccountClient(this.context.connectedDc.client);
169
- // 调用账户绑定API
170
- await accountClient.accountBind(req, mnemonic, this.context);
171
-
172
- // 绑定成功
173
- return [NFTBindStatus.Success, null];
174
- } catch (error) {
175
- // 错误处理,匹配各种特定错误类型
176
- const errorMsg = error instanceof Error ? error.message : String(error);
177
- if (errorMsg.includes("user already binded")) {
178
- return [
179
- NFTBindStatus.UserBinded,
180
- error instanceof Error ? error : new Error(errorMsg),
181
- ];
182
- } else if (errorMsg.includes("account already binded")) {
183
- return [
184
- NFTBindStatus.NftAccountBinded,
185
- error instanceof Error ? error : new Error(errorMsg),
186
- ];
187
- } else if (errorMsg.includes("user space expired")) {
188
- return [
189
- NFTBindStatus.SpaceExpired,
190
- error instanceof Error ? error : new Error(errorMsg),
191
- ];
192
- } else if (errorMsg.includes("no enough user space")) {
193
- return [
194
- NFTBindStatus.NoLeftSpace,
195
- error instanceof Error ? error : new Error(errorMsg),
196
- ];
197
- } else {
198
- console.error("NFT账号绑定失败:", error);
199
- return [
200
- NFTBindStatus.Error,
201
- error instanceof Error ? error : new Error(errorMsg),
202
- ];
203
- }
204
- }
205
- }
206
-
207
- /**
208
- * 生成Nft账号处理的请求(包括绑定NFT账号以及修改账号对应的登录信息),
209
- * 如果登录账号的助记词存在,则使用助记词进行绑定,否则使用私钥进行绑定
210
- *
211
- * @param account NFT账号
212
- * @param password 密码
213
- * @param seccode 安全码
214
- * @param serverPid 服务器节点ID
215
- * @param isParent 是否为父账户
216
- * @returns [AccountDealRequest对象, 状态码]
217
- */
218
- private async generateAccountDealRequest(
219
- account: string,
220
- password: string,
221
- seccode: string,
222
- mnemonic: string,
223
- serverPid: PeerId
224
- ): Promise<
225
- [
226
- {
227
- accounthashencrypt: Uint8Array;
228
- accountencrypt: Uint8Array;
229
- prikeyencrypt2: Uint8Array;
230
- blockheight: number;
231
- loginkeyrandencrypt: Uint8Array;
232
- peerid: Uint8Array;
233
- signature: Uint8Array;
234
- } | null,
235
- NFTBindStatus
236
- ]
237
- > {
238
- try {
239
- // 确定要加密的内容(私钥或助记词)
240
- const needEncryptStr = `mnemonic:${mnemonic}`;
241
- // 哈希账号
242
- const accountBytes = new TextEncoder().encode(account);
243
- const accountHash = await crypto.subtle.digest("SHA-256", accountBytes);
244
- const accountHashArray = new Uint8Array(accountHash);
245
-
246
- // 获取节点公钥
247
- const serverPubkey = await extractPublicKeyFromPeerId(serverPid);
248
- if (!serverPubkey) {
249
- return [null, NFTBindStatus.Error];
250
- }
251
-
252
- // 确定使用的密钥
253
- // 生成
254
- const keymanager = new KeyManager();
255
- const selfPrivkey = await keymanager.getEd25519KeyFromMnemonic(mnemonic, "");
256
- const selfPubkey = selfPrivkey.publicKey;
257
-
258
- // 用自身公钥加密账号
259
- const accountEncrypt = await selfPubkey.encrypt(
260
- new TextEncoder().encode(account)
261
- );
262
- if (!accountEncrypt) {
263
- return [null, NFTBindStatus.EncryptError];
264
- }
265
-
266
- // 用服务器公钥加密账号哈希
267
- const accountHashCrypt = await serverPubkey.encrypt(accountHashArray);
268
- if (!accountHashCrypt) {
269
- return [null, NFTBindStatus.EncryptError];
270
- }
271
- // 生成对称密钥
272
- const aeskey = await generateSymKeyForPrikey(account, password);
273
- if (!aeskey) {
274
- return [null, NFTBindStatus.EncryptError];
275
- }
276
- const encryptKey = SymmetricKey.fromSymKey(aeskey);
277
- // 用对称密钥加密私钥/助记词
278
- const prikeyencrypt = await encryptKey.encrypt(
279
- new TextEncoder().encode(needEncryptStr)
280
- );
281
- if (!prikeyencrypt) {
282
- return [null, NFTBindStatus.EncryptError];
283
- }
284
- // 用服务器公钥再次加密
285
- const prikeyencrypt2 = await serverPubkey.encrypt(prikeyencrypt);
286
- if (!prikeyencrypt2) {
287
- return [null, NFTBindStatus.EncryptError];
288
- }
289
- // 获取区块链高度
290
- if (!this.chainUtil) {
291
- return [null, NFTBindStatus.BlockchainError];
292
- }
293
-
294
- const blockHeight = await this.chainUtil.getBlockHeight();
295
- if (blockHeight === undefined) {
296
- return [null, NFTBindStatus.BlockchainError];
297
- }
298
-
299
- // 生成随机密钥
300
- const randKey = new Uint8Array(32);
301
- crypto.getRandomValues(randKey);
302
-
303
- // 生成登录密钥
304
- const passwordBytes = new TextEncoder().encode(password);
305
- const passwordHashBytes = new Uint8Array(
306
- await crypto.subtle.digest("SHA-256", passwordBytes.slice(0, 2))
307
- );
308
-
309
- // 组合登录密钥种子
310
- const loginKeySeed = new Uint8Array(
311
- accountHashArray.length + 2 + new TextEncoder().encode(seccode).length
312
- );
313
- loginKeySeed.set(accountHashArray, 0);
314
- loginKeySeed.set(passwordHashBytes.slice(-2), accountHashArray.length);
315
- loginKeySeed.set(
316
- new TextEncoder().encode(seccode),
317
- accountHashArray.length + 2
318
- );
319
-
320
- // 计算登录密钥
321
- const loginKeyHash = await crypto.subtle.digest("SHA-256", loginKeySeed);
322
- const loginkey = new Uint8Array(loginKeyHash);
323
-
324
- // 加密登录密钥和随机密钥
325
- const loginRandKey = new Uint8Array(loginkey.length + randKey.length);
326
- loginRandKey.set(loginkey, 0);
327
- loginRandKey.set(randKey, loginkey.length);
328
-
329
- const loginkeyRandEncrypt = await serverPubkey.encrypt(loginRandKey);
330
- if (!loginkeyRandEncrypt) {
331
- return [null, NFTBindStatus.EncryptError];
332
- }
333
-
334
- // 准备签名数据
335
- const serverPidBytes = new TextEncoder().encode(serverPid.toString());
336
- const prikeyencryptHash = new Uint8Array(
337
- await crypto.subtle.digest("SHA-256", prikeyencrypt as any)
338
- );
339
-
340
- // 区块高度转为小端字节序
341
- const hvalue = uint32ToLittleEndianBytes(blockHeight);
342
-
343
- // 组合预签名数据
344
- const preSign = new Uint8Array(
345
- accountHashArray.length +
346
- accountEncrypt.length +
347
- prikeyencryptHash.length +
348
- hvalue.length +
349
- serverPidBytes.length
350
- );
351
- console.log("accountHashArray:", accountHashArray);
352
- console.log("accountEncrypt:", accountEncrypt);
353
- console.log("prikeyencryptHash:", prikeyencryptHash);
354
- console.log("hvalue:", hvalue);
355
- console.log("serverPidBytes:", serverPidBytes);
356
-
357
- let offset = 0;
358
- preSign.set(accountHashArray, offset);
359
- offset += accountHashArray.length;
360
- preSign.set(accountEncrypt, offset);
361
- offset += accountEncrypt.length;
362
- preSign.set(prikeyencryptHash, offset);
363
- offset += prikeyencryptHash.length;
364
- preSign.set(hvalue, offset);
365
- offset += hvalue.length;
366
- preSign.set(serverPidBytes, offset);
367
-
368
- // 签名
369
- let signature: Uint8Array;
370
- if(selfPrivkey != null){
371
- signature = selfPrivkey.sign(preSign);
372
- }else {
373
- signature = await this.context.sign(preSign);
374
- }
375
- if (!signature) {
376
- return [null, NFTBindStatus.SignError];
377
- }
378
- // 创建请求对象
379
- const req = {
380
- accounthashencrypt: accountHashCrypt,
381
- accountencrypt: accountEncrypt,
382
- prikeyencrypt2: prikeyencrypt2,
383
- blockheight: blockHeight,
384
- loginkeyrandencrypt: loginkeyRandEncrypt,
385
- peerid: serverPidBytes,
386
- signature: signature,
387
- };
388
-
389
- return [req, NFTBindStatus.Success];
390
- } catch (error) {
391
- console.error("生成账户请求失败:", error);
392
- return [null, NFTBindStatus.Error];
393
- }
394
- }
395
-
396
- /**
397
- * 检查NFT账号是否成功绑定到用户的公钥
398
- * @param nftAccount NFT账号
399
- * @param pubKeyStr 公钥字符串
400
- * @returns 是否成功绑定
401
- */
402
- async isNftAccountBindSuccess(
403
- nftAccount: string,
404
- pubKeyStr: string
405
- ): Promise<boolean> {
406
- try {
407
- if (!this.chainUtil || !this.chainUtil.dcchainapi) {
408
- return false;
409
- }
410
- const accountBytes = new TextEncoder().encode(nftAccount);
411
- const accountHash = await sha256(accountBytes);
412
- const nftHexAccount = "0x" + Buffer.from(accountHash).toString("hex");
413
- const walletAccount =
414
- await (this.chainUtil.dcchainapi?.query as any).dcNode.nftToWalletAccount(
415
- nftHexAccount
416
- );
417
- // 比较公钥
418
- return (
419
- walletAccount.toString() ==
420
- (pubKeyStr.indexOf("0x") === 0 ? pubKeyStr : "0x" + pubKeyStr)
421
- );
422
- } catch (error) {
423
- console.error("检查NFT账号绑定状态失败:", error);
424
- return false;
425
- }
426
- }
427
-
428
- /**
429
- * 检查NFT账号是否已经被绑定
430
- * @param nftAccount NFT账号
431
- * @returns 是否被其他账号绑定
432
- */
433
- async isNftAccountBinded(nftAccount: string): Promise<boolean> {
434
- try {
435
- if (!this.chainUtil || !this.chainUtil.dcchainapi) {
436
- return false;
437
- }
438
- const accountBytes = new TextEncoder().encode(nftAccount);
439
- const accountHash = await sha256(accountBytes);
440
- const nftHexAccount = "0x" + Buffer.from(accountHash).toString("hex");
441
- const walletAccount =
442
- await (this.chainUtil.dcchainapi?.query as any).dcNode.nftToWalletAccount(
443
- nftHexAccount
444
- );
445
- if (!walletAccount.toString()) {
446
- return false;
447
- }
448
- } catch (error) {
449
- console.error("检查NFT账号绑定状态失败:", error);
450
- return false;
451
- }
452
- return true;
453
- }
454
-
455
- /**
456
- * 创建子账号,只有带有助记词的用户才能创建子账号
457
- * 子账号创建后,用助记词登陆子账号App,与调用登陆了主账号的App进行授权登陆,是同一个用户
458
- *
459
- * @param appId 应用ID
460
- * @returns [私钥字符串,基于base32编码, 错误]
461
- */
462
- async generateAppAccount(
463
- appId: string,
464
- mnemonic: string
465
- ): Promise<[string | null, Error | null]> {
466
- if (!mnemonic) {
467
- return [null, new AccountError("Mnemonic is required")];
468
- }
469
- if (!appId) {
470
- return [null, new AccountError("App ID is required")];
471
- }
472
- if (!this.context.connectedDc.nodeAddr) {
473
- return [null, new AccountError("No connected node")];
474
- }
475
- let subPrivateKey: Ed25519PrivKey;
476
- try {
477
- // 生成有效的应用子账号
478
- const keymanager = new KeyManager();
479
- subPrivateKey = await keymanager.getEd25519KeyFromMnemonic(
480
- mnemonic,
481
- appId
482
- );
483
- // 获取公钥
484
- const subPubkey = subPrivateKey.publicKey;
485
- const existFlag = await this.isAppAccountExists(subPubkey.toString());
486
- if (existFlag) {
487
- return [subPrivateKey.string(), null];
488
- }
489
- // 获取当前区块高度
490
- const blockHeight = await this.chainUtil?.getBlockHeight();
491
- if (blockHeight === undefined) {
492
- return [null, new AccountError("Failed to get blockchain height")];
493
- }
494
- // 获取服务器节点ID
495
- const serverPidStr = this.context.connectedDc.nodeAddr.getPeerId();
496
- if (!serverPidStr) {
497
- return [null, new AccountError("No connected peer ID")];
498
- }
499
- const serverPidBytes = new TextEncoder().encode(serverPidStr);
500
-
501
- // 生成签名数据
502
- const hvalue = uint32ToLittleEndianBytes(blockHeight);
503
-
504
- // 组合预签名数据: subPubkey + blockHeight + peerid
505
- const preSign = new Uint8Array(
506
- subPubkey.raw.length + hvalue.length + serverPidBytes.length
507
- );
508
-
509
- let offset = 0;
510
- preSign.set(subPubkey.raw, offset);
511
- offset += subPubkey.raw.length;
512
- preSign.set(hvalue, offset);
513
- offset += hvalue.length;
514
- preSign.set(serverPidBytes, offset);
515
-
516
- // 使用父私钥签名
517
- const privateKey = await keymanager.getEd25519KeyFromMnemonic(
518
- mnemonic,
519
- ""
520
- );
521
- const signature = privateKey.sign(preSign);
522
- if (!signature) {
523
- return [
524
- null,
525
- new AccountError("Failed to sign with parent private key"),
526
- ];
527
- }
528
-
529
- // 获取token
530
- if (!this.context.connectedDc.client) {
531
- throw [null, Errors.ErrNoAccountPeerConnected];
532
- }
533
- if (this.context.connectedDc.client.token == "") {
534
- const token = await this.context.connectedDc.client.GetToken(
535
- this.context.appInfo.appId || "",
536
- privateKey.publicKey.string(),
537
- async (payload: Uint8Array): Promise<Uint8Array> => {
538
- return privateKey.sign(payload);
539
- }
540
- );
541
- if (!token) {
542
- return [null, new AccountError("Failed to get token")];
543
- }
544
- }
545
-
546
- // 创建请求对象
547
- const req = {
548
- subpubkey: subPubkey.raw,
549
- blockheight: blockHeight,
550
- peerid: serverPidBytes,
551
- signature: signature,
552
- };
553
-
554
- const client = new AccountClient(this.context.connectedDc.client);
555
- // 添加子公钥
556
- await client.addSubPubkey(req);
557
- // Wait for app account creation
558
- let waitCount = 0;
559
- while (true) {
560
- // Check if app account exists
561
- try {
562
- const accountExists = await this.isAppAccountExists(
563
- subPubkey.toString()
564
- );
565
- if (accountExists) {
566
- break;
567
- }
568
- } catch (err) {
569
- console.warn("Error checking app account status:", err);
570
- }
571
- // Sleep for 1 second
572
- await new Promise((resolve) => setTimeout(resolve, 1000));
573
- waitCount++;
574
- if (waitCount > 30) {
575
- try {
576
- const accountExists = await this.isAppAccountExists(
577
- subPubkey.toString()
578
- );
579
- if (accountExists) {
580
- break;
581
- }
582
- } catch (err) {
583
- // Ignore error on final check
584
- }
585
- // Timeout after ~30 seconds
586
- return [null, new AccountError("Wait app account create timeout")];
587
- }
588
- }
589
- // 返回编码后的私钥
590
- return [subPrivateKey.string(), null];
591
- } catch (error) {
592
- console.error("Failed to generate app account:", error);
593
- return [null, error instanceof Error ? error : new Error(String(error))];
594
- }
595
- }
596
-
597
- /**
598
- * Check if an application account exists
599
- * @param pubkeyStr The public key string of the account to check
600
- * @returns True if the account exists, false otherwise
601
- */
602
- private async isAppAccountExists(pubkeyStr: string): Promise<boolean> {
603
- try {
604
- const account =
605
- pubkeyStr.indexOf("0x") === 0 ? pubkeyStr : "0x" + pubkeyStr;
606
- const user = await this.context.dcChain?.getUserInfoWithAccount(account);
607
- return !!user;
608
- } catch (error) {
609
- return false;
610
- }
611
- }
612
- /**
613
- * 获取用户默认数据库
614
- * @param threadId 数据库ID
615
- * @param rk 读取密钥,主要用来加解密真正的数据,注意对数据记录进行加密和解密
616
- * @param sk 服务密钥,主要用来处理传输过程加解密,主要对数据链表头进行加密和解密
617
- * @param remark 备注信息
618
- * @returns 用户默认数据库信息
619
- */
620
- async setUserDefaultDB(
621
- threadId: string,
622
- rk: string,
623
- sk: string,
624
- remark: string,
625
- vaccount?: string
626
- ): Promise<void> {
627
- if(!this.context.publicKey){
628
- throw Errors.ErrAccountPublicKeyIsNull;
629
- }
630
- if(!this.context.connectedDc.client){
631
- throw Errors.ErrNoDcPeerConnected;
632
- }
633
- if(!this.context.connectedDc.nodeAddr){
634
- throw Errors.ErrNodeAddrIsNull;
635
- }
636
- const dbinfo = threadId + "|" + rk + "|" + sk + "|" + remark;
637
- const dbinfocrypto = await this.context.publicKey.encrypt(
638
- new TextEncoder().encode(dbinfo)
639
- );
640
- const blockHeight = await this.chainUtil?.getBlockHeight();
641
- if (blockHeight === undefined) {
642
- throw new AccountError("Failed to get blockchain height");
643
- }
644
- if (this.context.connectedDc.client.token == "") {
645
- const token = await this.context.connectedDc.client.GetToken(
646
- this.context.appInfo.appId || "",
647
- this.context.publicKey.string(),
648
- async (payload: Uint8Array): Promise<Uint8Array> => {
649
- return this.context.sign(payload);
650
- }
651
- );
652
- if (!token) {
653
- throw new AccountError("Failed to get token");
654
- }
655
- }
656
- const accountClient = new AccountClient(this.context.connectedDc.client);
657
- const serverPidStr = this.context.connectedDc.nodeAddr.getPeerId() || "";
658
- const serverPidBytes = new TextEncoder().encode(serverPidStr);
659
- // 生成签名数据
660
- const hvalue = uint32ToLittleEndianBytes(blockHeight);
661
- // 组合预签名数据: subPubkey + blockHeight + peerid
662
- const preSign = new Uint8Array(
663
- dbinfocrypto.length + hvalue.length + serverPidBytes.length
664
- );
665
- let offset = 0;
666
- preSign.set(dbinfocrypto, offset);
667
- offset += dbinfocrypto.length;
668
- preSign.set(hvalue, offset);
669
- offset += hvalue.length;
670
- preSign.set(serverPidBytes, offset);
671
- // 使用私钥签名
672
- const signature = await this.context.sign(preSign);
673
-
674
- await accountClient.setUserDefaultDB(
675
- dbinfocrypto,
676
- blockHeight ? blockHeight : 0,
677
- serverPidStr,
678
- signature,
679
- vaccount
680
- );
681
- return;
682
- }
683
- }