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,1151 +0,0 @@
|
|
|
1
|
-
import { DCConnectInfo, ThemeAuthInfo, ThemeComment, ThemeObj } from "../../common/types/types";
|
|
2
|
-
import type { HeliaLibp2p } from "helia";
|
|
3
|
-
import { ChainUtil } from "../../common/chain";
|
|
4
|
-
import { base32 } from 'multiformats/bases/base32'
|
|
5
|
-
|
|
6
|
-
import { DcUtil } from "../../common/dcutil";
|
|
7
|
-
import * as buffer from "buffer/";
|
|
8
|
-
import { extractPeerIdFromMultiaddr } from "../../common/dc-key/keyManager";
|
|
9
|
-
import { Multiaddr } from "@multiformats/multiaddr";
|
|
10
|
-
import { CommentClient } from "./client";
|
|
11
|
-
import { parseUint32, sha256, uint32ToLittleEndianBytes } from "../../util/utils";
|
|
12
|
-
import { FileManager } from "../file/manager";
|
|
13
|
-
import { cidNeedConnect } from "../../common/constants";
|
|
14
|
-
import { toString as uint8ArrayToString } from "uint8arrays/to-string";
|
|
15
|
-
import { BrowserLineReader, readLine } from "../../util/BrowserLineReader";
|
|
16
|
-
import { bytesToHex } from "@noble/curves/abstract/utils";
|
|
17
|
-
import { dcnet } from "../../proto/dcnet_proto";
|
|
18
|
-
import { DCContext } from "../../../lib/interfaces/DCContext";
|
|
19
|
-
import { publicKeyFromRaw } from "@libp2p/crypto/keys";
|
|
20
|
-
import { Ed25519PubKey } from "../../common/dc-key/ed25519";
|
|
21
|
-
import { CommentType, Direction } from "../../common/define";
|
|
22
|
-
import { SymmetricKey } from "../threaddb/common/key";
|
|
23
|
-
import { Libp2p } from "@libp2p/interface";
|
|
24
|
-
const { Buffer } = buffer;
|
|
25
|
-
|
|
26
|
-
// 创建一个可以取消的信号
|
|
27
|
-
const controller = new AbortController();
|
|
28
|
-
const { signal } = controller;
|
|
29
|
-
|
|
30
|
-
// 错误定义
|
|
31
|
-
export class CommentError extends Error {
|
|
32
|
-
constructor(message: string) {
|
|
33
|
-
super(message);
|
|
34
|
-
this.name = "CommentError";
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export const Errors = {
|
|
38
|
-
ErrNoDcPeerConnected: new CommentError("no dc peer connected"),
|
|
39
|
-
ErrNodeAddrIsNull: new CommentError("nodeAddr is null"),
|
|
40
|
-
ErrNoFileChose: new CommentError("no file choose"),
|
|
41
|
-
ErrNoPeerIdIsNull: new CommentError("peerId is null"),
|
|
42
|
-
ErrAddThemeObj: new CommentError("add theme obj error"),
|
|
43
|
-
ErrDeleteThemeObj: new CommentError("delete theme obj error"),
|
|
44
|
-
ErrPublishCommentToTheme: new CommentError("publish comment error"),
|
|
45
|
-
// 评论空间没有配置
|
|
46
|
-
ErrCommentSpaceNotConfig: new CommentError("comment space not config"),
|
|
47
|
-
// 评论数据同步中
|
|
48
|
-
ErrCommentDataSync: new CommentError("comment data sync"),
|
|
49
|
-
// publickey is null
|
|
50
|
-
ErrPublicKeyIsNull: new CommentError("publickey is null"),
|
|
51
|
-
ErrCommentKeyInvalid: new CommentError("comment key invalid"),
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export class CommentManager {
|
|
55
|
-
dc: DcUtil;
|
|
56
|
-
connectedDc: DCConnectInfo = {};
|
|
57
|
-
dcNodeClient: HeliaLibp2p<Libp2p>;
|
|
58
|
-
chainUtil: ChainUtil;
|
|
59
|
-
context:DCContext
|
|
60
|
-
constructor(
|
|
61
|
-
context: DCContext,
|
|
62
|
-
) {
|
|
63
|
-
this.dc = context.dcutil;
|
|
64
|
-
this.connectedDc = context.connectedDc;
|
|
65
|
-
this.dcNodeClient = context.dcNodeClient;
|
|
66
|
-
this.chainUtil = context.dcChain;
|
|
67
|
-
this.context = context;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 配置或增加用户自身的评论空间 0:成功 1:失败
|
|
71
|
-
async addUserOffChainSpace(): Promise<[boolean | null, Error | null]> {
|
|
72
|
-
try {
|
|
73
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
74
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
75
|
-
}
|
|
76
|
-
if (!this.context.AccountBackupDc?.nodeAddr) {
|
|
77
|
-
return [null, Errors.ErrNodeAddrIsNull];
|
|
78
|
-
}
|
|
79
|
-
const peerAddr = this.context.AccountBackupDc.nodeAddr;
|
|
80
|
-
const peerId = await extractPeerIdFromMultiaddr(peerAddr);
|
|
81
|
-
|
|
82
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
83
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
84
|
-
blockHeight ? blockHeight : 0
|
|
85
|
-
);
|
|
86
|
-
const peerIdValue: Uint8Array = new TextEncoder().encode(peerId.toString());
|
|
87
|
-
|
|
88
|
-
// 将 hValue 和 peerIdValue 连接起来
|
|
89
|
-
const preSign = new Uint8Array(peerIdValue.length + hValue.length);
|
|
90
|
-
preSign.set(peerIdValue, 0);
|
|
91
|
-
preSign.set(hValue, peerIdValue.length);
|
|
92
|
-
const signature = await this.context.sign(preSign);
|
|
93
|
-
const userPubkey = this.context.getPublicKey();
|
|
94
|
-
|
|
95
|
-
console.log("AddUserOffChainSpace peerId", peerId);
|
|
96
|
-
const commentClient = new CommentClient(
|
|
97
|
-
this.context.AccountBackupDc.client,
|
|
98
|
-
this.dcNodeClient,
|
|
99
|
-
this.context
|
|
100
|
-
);
|
|
101
|
-
const res = await commentClient.addUserOffChainSpace(
|
|
102
|
-
userPubkey.string(),
|
|
103
|
-
blockHeight || 0,
|
|
104
|
-
peerId.toString(),
|
|
105
|
-
signature
|
|
106
|
-
);
|
|
107
|
-
return [true, null];
|
|
108
|
-
} catch (err) {
|
|
109
|
-
console.error("AddUserOffChainSpace error:", err);
|
|
110
|
-
throw err;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async addThemeObj(
|
|
115
|
-
appId: string,
|
|
116
|
-
theme: string,
|
|
117
|
-
openFlag:number,
|
|
118
|
-
commentSpace: number,
|
|
119
|
-
): Promise<[number | null, Error | null]> {
|
|
120
|
-
try {
|
|
121
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
122
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
123
|
-
}
|
|
124
|
-
if (!this.context.publicKey) {
|
|
125
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
126
|
-
}
|
|
127
|
-
if(this.context.AccountBackupDc.client.token == ""){
|
|
128
|
-
await this.context.AccountBackupDc.client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
129
|
-
}
|
|
130
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
131
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
132
|
-
blockHeight ? blockHeight : 0
|
|
133
|
-
);
|
|
134
|
-
const spaceValue: Uint8Array = uint32ToLittleEndianBytes(commentSpace);
|
|
135
|
-
const statusValue: Uint8Array = uint32ToLittleEndianBytes(openFlag);
|
|
136
|
-
|
|
137
|
-
const themeValue: Uint8Array = new TextEncoder().encode(theme);
|
|
138
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
139
|
-
const preSign = new Uint8Array([
|
|
140
|
-
...themeValue,
|
|
141
|
-
...appIdValue,
|
|
142
|
-
...hValue,
|
|
143
|
-
...spaceValue,
|
|
144
|
-
...statusValue,
|
|
145
|
-
]);
|
|
146
|
-
const signature = await this.context.sign(preSign);
|
|
147
|
-
const userPubkey = this.context.getPublicKey();
|
|
148
|
-
const commentClient = new CommentClient(
|
|
149
|
-
this.context.AccountBackupDc.client,
|
|
150
|
-
this.dcNodeClient,
|
|
151
|
-
this.context
|
|
152
|
-
);
|
|
153
|
-
let res = await commentClient.addThemeObj(
|
|
154
|
-
appId,
|
|
155
|
-
theme,
|
|
156
|
-
blockHeight || 0,
|
|
157
|
-
commentSpace,
|
|
158
|
-
userPubkey.string(),
|
|
159
|
-
openFlag,
|
|
160
|
-
signature,
|
|
161
|
-
);
|
|
162
|
-
// res 0:成功 1:评论空间没有配置 2:评论空间不足 3:评论数据同步中
|
|
163
|
-
if(res === 0){
|
|
164
|
-
return [res, null];
|
|
165
|
-
}
|
|
166
|
-
// if(res === 1){
|
|
167
|
-
// // 评论空间没有配置
|
|
168
|
-
// return [null, Errors.ErrCommentSpaceNotConfig];
|
|
169
|
-
// }
|
|
170
|
-
if(res == 1 || res === 2){
|
|
171
|
-
// 添加空间
|
|
172
|
-
await this.addUserOffChainSpace();
|
|
173
|
-
// 继续调用
|
|
174
|
-
res = await commentClient.addThemeObj(
|
|
175
|
-
appId,
|
|
176
|
-
theme,
|
|
177
|
-
blockHeight || 0,
|
|
178
|
-
commentSpace,
|
|
179
|
-
userPubkey.string(),
|
|
180
|
-
openFlag,
|
|
181
|
-
signature,
|
|
182
|
-
);
|
|
183
|
-
if(res === 0){
|
|
184
|
-
return [res, null];
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
if(res === 3){
|
|
188
|
-
// 评论数据同步中
|
|
189
|
-
return [null, Errors.ErrCommentDataSync];
|
|
190
|
-
}
|
|
191
|
-
return [null, Errors.ErrAddThemeObj]
|
|
192
|
-
} catch (err) {
|
|
193
|
-
console.error("addThemeObj error:", err);
|
|
194
|
-
throw err;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
async deleteThemeObj(
|
|
201
|
-
appId: string,
|
|
202
|
-
theme: string
|
|
203
|
-
): Promise<[number | null, Error | null]> {
|
|
204
|
-
try {
|
|
205
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
206
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
207
|
-
}
|
|
208
|
-
if (!this.context.publicKey) {
|
|
209
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
210
|
-
}
|
|
211
|
-
if(this.context.AccountBackupDc.client.token == ""){
|
|
212
|
-
await this.context.AccountBackupDc.client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
213
|
-
}
|
|
214
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
215
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
216
|
-
blockHeight ? blockHeight : 0
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const themeValue: Uint8Array = new TextEncoder().encode(theme);
|
|
220
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
221
|
-
const preSign = new Uint8Array([
|
|
222
|
-
...themeValue,
|
|
223
|
-
...appIdValue,
|
|
224
|
-
...hValue,
|
|
225
|
-
]);
|
|
226
|
-
const signature = await this.context.sign(preSign);
|
|
227
|
-
const userPubkey = this.context.getPublicKey();
|
|
228
|
-
const commentClient = new CommentClient(
|
|
229
|
-
this.context.AccountBackupDc.client,
|
|
230
|
-
this.dcNodeClient,
|
|
231
|
-
this.context
|
|
232
|
-
);
|
|
233
|
-
let res = await commentClient.deleteThemeObj(
|
|
234
|
-
appId,
|
|
235
|
-
theme,
|
|
236
|
-
blockHeight || 0,
|
|
237
|
-
userPubkey.string(),
|
|
238
|
-
signature,
|
|
239
|
-
);
|
|
240
|
-
// res 0:成功 1:评论空间没有配置 2:评论空间不足 3:评论数据同步中
|
|
241
|
-
if(res === 0){
|
|
242
|
-
return [res, null];
|
|
243
|
-
}
|
|
244
|
-
// if(res === 1){
|
|
245
|
-
// // 评论空间没有配置
|
|
246
|
-
// return [null, Errors.ErrCommentSpaceNotConfig];
|
|
247
|
-
// }
|
|
248
|
-
if(res == 1 || res === 2){
|
|
249
|
-
// 添加空间
|
|
250
|
-
await this.addUserOffChainSpace();
|
|
251
|
-
// 继续调用
|
|
252
|
-
res = await commentClient.deleteThemeObj(
|
|
253
|
-
appId,
|
|
254
|
-
theme,
|
|
255
|
-
blockHeight || 0,
|
|
256
|
-
userPubkey.string(),
|
|
257
|
-
signature,
|
|
258
|
-
);
|
|
259
|
-
if(res === 0){
|
|
260
|
-
return [res, null];
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if(res === 3){
|
|
264
|
-
// 评论数据同步中
|
|
265
|
-
return [null, Errors.ErrCommentDataSync];
|
|
266
|
-
}
|
|
267
|
-
return [null, Errors.ErrDeleteThemeObj]
|
|
268
|
-
} catch (err) {
|
|
269
|
-
console.error("deleteThemeObj error:", err);
|
|
270
|
-
throw err;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
async isThemeExist(
|
|
275
|
-
appId: string,
|
|
276
|
-
theme: string,
|
|
277
|
-
themeAuthor: string,
|
|
278
|
-
): Promise<[boolean | null, Error | null]> {
|
|
279
|
-
try {
|
|
280
|
-
if (!this.connectedDc?.client) {
|
|
281
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
282
|
-
}
|
|
283
|
-
if (!this.context.publicKey) {
|
|
284
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
285
|
-
}
|
|
286
|
-
let client = this.context.AccountBackupDc.client;
|
|
287
|
-
if (!client ||themeAuthor != this.context.publicKey.string()) {//查询他人主题评论
|
|
288
|
-
const authorPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
289
|
-
const connectedClient = await this.dc.connectToUserDcPeer(authorPublicKey.raw);
|
|
290
|
-
if (!connectedClient) {
|
|
291
|
-
return [null, Errors.ErrNoPeerIdIsNull];
|
|
292
|
-
}
|
|
293
|
-
client = connectedClient;
|
|
294
|
-
}
|
|
295
|
-
if(client.token == ""){
|
|
296
|
-
await client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
297
|
-
}
|
|
298
|
-
const aesKey = SymmetricKey.new();// 生成aeskey文件加密密码
|
|
299
|
-
const commentClient = new CommentClient(
|
|
300
|
-
client,
|
|
301
|
-
this.dcNodeClient,
|
|
302
|
-
this.context
|
|
303
|
-
);
|
|
304
|
-
const res = await commentClient.isThemeExist(appId, theme, themeAuthor);
|
|
305
|
-
return [res, null];
|
|
306
|
-
} catch (err) {
|
|
307
|
-
return [null, err as Error];
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
async getUserOffChainUsedInfo(vaccount: string = ""): Promise<[dcnet.pb.GetUserOffChainUsedInfoReply | null, Error | null]> {
|
|
312
|
-
try {
|
|
313
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
314
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
315
|
-
}
|
|
316
|
-
if(!this.context.AccountBackupDc?.nodeAddr){
|
|
317
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
318
|
-
}
|
|
319
|
-
const commentClient = new CommentClient(
|
|
320
|
-
this.context.AccountBackupDc.client,
|
|
321
|
-
this.dcNodeClient,
|
|
322
|
-
this.context
|
|
323
|
-
);
|
|
324
|
-
const res = await commentClient.getUserOffChainUsedInfo(vaccount);
|
|
325
|
-
return [res, null];
|
|
326
|
-
} catch (err) {
|
|
327
|
-
return [null, err as Error];
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
async addUserOffChainOpTimes(
|
|
332
|
-
times: number,
|
|
333
|
-
vaccount: string = "",
|
|
334
|
-
): Promise<[boolean | null, Error | null]> {
|
|
335
|
-
try {
|
|
336
|
-
// 检查连接
|
|
337
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
338
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
339
|
-
}
|
|
340
|
-
if(!this.context.AccountBackupDc?.nodeAddr){
|
|
341
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// 检查公钥
|
|
345
|
-
if (!this.context.publicKey) {
|
|
346
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
347
|
-
}
|
|
348
|
-
if(this.context.AccountBackupDc.client.token == ""){
|
|
349
|
-
await this.context.AccountBackupDc.client.GetToken(
|
|
350
|
-
this.context.appInfo.appId || "",
|
|
351
|
-
this.context.publicKey.string(),
|
|
352
|
-
this.context.sign);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
// 获取区块链高度
|
|
356
|
-
let blockHeight = await this.chainUtil.getBlockHeight() || 0;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
// 准备签名数据
|
|
360
|
-
const hValue = uint32ToLittleEndianBytes(blockHeight);
|
|
361
|
-
const tValue = uint32ToLittleEndianBytes(times);
|
|
362
|
-
const peerId = this.context.AccountBackupDc?.nodeAddr.getPeerId() || "";
|
|
363
|
-
const peerIdBytes = new TextEncoder().encode(peerId);
|
|
364
|
-
const preSign = new Uint8Array([
|
|
365
|
-
...peerIdBytes,
|
|
366
|
-
...tValue,
|
|
367
|
-
...hValue
|
|
368
|
-
]);
|
|
369
|
-
|
|
370
|
-
// 签名
|
|
371
|
-
const signature = await this.context.sign(preSign);
|
|
372
|
-
const userPubkey = this.context.getPublicKey();
|
|
373
|
-
|
|
374
|
-
const client = new CommentClient(
|
|
375
|
-
this.context.AccountBackupDc.client,
|
|
376
|
-
this.dcNodeClient,
|
|
377
|
-
this.context
|
|
378
|
-
);
|
|
379
|
-
|
|
380
|
-
try {
|
|
381
|
-
// 第一次尝试调用
|
|
382
|
-
const res = await client.addUserOffChainOpTimes(userPubkey.string(), blockHeight, peerId, times, signature, vaccount);
|
|
383
|
-
return [res, null];
|
|
384
|
-
} catch (err: any) {
|
|
385
|
-
return [false, err as Error];
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
} catch (err) {
|
|
389
|
-
console.error("addUserOffChainOpTimes error:", err);
|
|
390
|
-
return [false, err as Error];
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
async addThemeSpace(
|
|
397
|
-
appId: string,
|
|
398
|
-
theme: string,
|
|
399
|
-
addSpace: number,
|
|
400
|
-
): Promise<[number | null, Error | null]> {
|
|
401
|
-
try {
|
|
402
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
403
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
404
|
-
}
|
|
405
|
-
if (!this.context.publicKey) {
|
|
406
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
407
|
-
}
|
|
408
|
-
if(this.context.AccountBackupDc.client.token == ""){
|
|
409
|
-
await this.context.AccountBackupDc.client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
410
|
-
}
|
|
411
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
412
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
413
|
-
blockHeight ? blockHeight : 0
|
|
414
|
-
);
|
|
415
|
-
const spaceValue: Uint8Array = uint32ToLittleEndianBytes(addSpace);
|
|
416
|
-
|
|
417
|
-
const themeValue: Uint8Array = new TextEncoder().encode(theme);
|
|
418
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
419
|
-
const preSign = new Uint8Array([
|
|
420
|
-
...themeValue,
|
|
421
|
-
...appIdValue,
|
|
422
|
-
...hValue,
|
|
423
|
-
...spaceValue,
|
|
424
|
-
]);
|
|
425
|
-
const signature = await this.context.sign(preSign);
|
|
426
|
-
const userPubkey = this.context.getPublicKey();
|
|
427
|
-
const commentClient = new CommentClient(
|
|
428
|
-
this.context.AccountBackupDc.client,
|
|
429
|
-
this.dcNodeClient,
|
|
430
|
-
this.context
|
|
431
|
-
);
|
|
432
|
-
const res = await commentClient.addThemeSpace(
|
|
433
|
-
appId,
|
|
434
|
-
theme,
|
|
435
|
-
blockHeight || 0,
|
|
436
|
-
addSpace,
|
|
437
|
-
userPubkey.string(),
|
|
438
|
-
signature,
|
|
439
|
-
);
|
|
440
|
-
return [res, null];
|
|
441
|
-
} catch (err) {
|
|
442
|
-
console.error("addThemeSpace error:", err);
|
|
443
|
-
throw err;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
async publishCommentToTheme(
|
|
448
|
-
appId: string,
|
|
449
|
-
theme: string,
|
|
450
|
-
themeAuthor: string,
|
|
451
|
-
commentType: number,
|
|
452
|
-
comment: string,
|
|
453
|
-
refercommentkey: string,
|
|
454
|
-
openFlag?: number
|
|
455
|
-
): Promise<[string | null, Error | null]> {
|
|
456
|
-
try {
|
|
457
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
458
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
459
|
-
}
|
|
460
|
-
if (!this.context.publicKey) {
|
|
461
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
462
|
-
}
|
|
463
|
-
if(this.context.AccountBackupDc.client.token == ""){
|
|
464
|
-
await this.context.AccountBackupDc.client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
465
|
-
}
|
|
466
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
467
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
468
|
-
blockHeight ? blockHeight : 0
|
|
469
|
-
);
|
|
470
|
-
const typeValue: Uint8Array = uint32ToLittleEndianBytes(commentType);
|
|
471
|
-
|
|
472
|
-
const commentUint8 = new TextEncoder().encode(comment);
|
|
473
|
-
const commenthash = await sha256(commentUint8);
|
|
474
|
-
const commentCidBase32 = base32.encode(commenthash)
|
|
475
|
-
|
|
476
|
-
const themeValue: Uint8Array = new TextEncoder().encode(theme);
|
|
477
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
478
|
-
const authValue: Uint8Array = new TextEncoder().encode(themeAuthor);
|
|
479
|
-
const cidValue: Uint8Array = new TextEncoder().encode(commentCidBase32);
|
|
480
|
-
const referValue: Uint8Array = new TextEncoder().encode(refercommentkey);
|
|
481
|
-
const preSign = new Uint8Array([
|
|
482
|
-
...themeValue,
|
|
483
|
-
...appIdValue,
|
|
484
|
-
...authValue,
|
|
485
|
-
...hValue,
|
|
486
|
-
...cidValue,
|
|
487
|
-
...referValue,
|
|
488
|
-
...typeValue,
|
|
489
|
-
]);
|
|
490
|
-
const signature = await this.context.sign(preSign);
|
|
491
|
-
const userPubkey = this.context.getPublicKey();
|
|
492
|
-
const commentClient = new CommentClient(
|
|
493
|
-
this.context.AccountBackupDc.client,
|
|
494
|
-
this.dcNodeClient,
|
|
495
|
-
this.context
|
|
496
|
-
);
|
|
497
|
-
let res = await commentClient.publishCommentToTheme(
|
|
498
|
-
appId,
|
|
499
|
-
theme,
|
|
500
|
-
themeAuthor,
|
|
501
|
-
blockHeight || 0,
|
|
502
|
-
userPubkey.string(),
|
|
503
|
-
commentType,
|
|
504
|
-
commentCidBase32,
|
|
505
|
-
comment,
|
|
506
|
-
refercommentkey,
|
|
507
|
-
signature,
|
|
508
|
-
openFlag,
|
|
509
|
-
);
|
|
510
|
-
// res 0:成功 1:评论空间没有配置 2:评论空间不足
|
|
511
|
-
if(res === 0){
|
|
512
|
-
// 获取高度
|
|
513
|
-
const commentBlockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
514
|
-
const commentKey = `${commentBlockHeight}/${commentCidBase32}`
|
|
515
|
-
return [commentKey, null];
|
|
516
|
-
}
|
|
517
|
-
// if(res === 1){
|
|
518
|
-
// // 评论空间没有配置
|
|
519
|
-
// return [null, Errors.ErrCommentSpaceNotConfig];
|
|
520
|
-
// }
|
|
521
|
-
if(res == 1 || res === 2){
|
|
522
|
-
// 添加空间
|
|
523
|
-
await this.addUserOffChainSpace();
|
|
524
|
-
// 继续调用
|
|
525
|
-
res = await commentClient.publishCommentToTheme(
|
|
526
|
-
appId,
|
|
527
|
-
theme,
|
|
528
|
-
themeAuthor,
|
|
529
|
-
blockHeight || 0,
|
|
530
|
-
userPubkey.string(),
|
|
531
|
-
commentType,
|
|
532
|
-
commentCidBase32,
|
|
533
|
-
comment,
|
|
534
|
-
refercommentkey,
|
|
535
|
-
signature,
|
|
536
|
-
);
|
|
537
|
-
if(res === 0){
|
|
538
|
-
// 获取高度
|
|
539
|
-
const commentBlockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
540
|
-
const commentKey = `${commentBlockHeight}/${commentCidBase32}`
|
|
541
|
-
return [commentKey, null];
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return [null, Errors.ErrPublishCommentToTheme]
|
|
545
|
-
} catch (err) {
|
|
546
|
-
console.error("publishCommentToTheme error:", err);
|
|
547
|
-
throw err;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
async deleteSelfComment(
|
|
552
|
-
appId: string,
|
|
553
|
-
theme: string,
|
|
554
|
-
themeAuthor: string,
|
|
555
|
-
commentKey: string,
|
|
556
|
-
): Promise<[number | null, Error | null]> {
|
|
557
|
-
try {
|
|
558
|
-
if (!this.context.AccountBackupDc?.client) {
|
|
559
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
560
|
-
}
|
|
561
|
-
if (!this.context.publicKey) {
|
|
562
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
563
|
-
}
|
|
564
|
-
if(this.context.AccountBackupDc.client.token == ""){
|
|
565
|
-
await this.context.AccountBackupDc.client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
566
|
-
}
|
|
567
|
-
const parts = commentKey.split("/");
|
|
568
|
-
if (parts.length < 2) {
|
|
569
|
-
return [null, Errors.ErrCommentKeyInvalid];
|
|
570
|
-
|
|
571
|
-
}
|
|
572
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
573
|
-
const commentCid = parts[1]!;
|
|
574
|
-
const commentBlockHeight = parts[0]!;
|
|
575
|
-
// commentBlockHeight 转32位无符号整数
|
|
576
|
-
const commentBlockHeightUint32 = parseUint32(commentBlockHeight);
|
|
577
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
578
|
-
blockHeight ? blockHeight : 0
|
|
579
|
-
);
|
|
580
|
-
const themeValue: Uint8Array = new TextEncoder().encode(theme);
|
|
581
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
582
|
-
const authValue: Uint8Array = new TextEncoder().encode(themeAuthor);
|
|
583
|
-
const cidValue: Uint8Array = new TextEncoder().encode(commentCid);
|
|
584
|
-
const preSign = new Uint8Array([
|
|
585
|
-
...themeValue,
|
|
586
|
-
...appIdValue,
|
|
587
|
-
...authValue,
|
|
588
|
-
...hValue,
|
|
589
|
-
...cidValue,
|
|
590
|
-
]);
|
|
591
|
-
const signature = await this.context.sign(preSign);
|
|
592
|
-
const userPubkey = this.context.getPublicKey();
|
|
593
|
-
const commentClient = new CommentClient(
|
|
594
|
-
this.context.AccountBackupDc.client,
|
|
595
|
-
this.dcNodeClient,
|
|
596
|
-
this.context
|
|
597
|
-
);
|
|
598
|
-
let delSelfRes: number = -1;
|
|
599
|
-
let delObjRes: number = -1;
|
|
600
|
-
let delSelfError: CommentError | null = null;
|
|
601
|
-
let delObjError: CommentError | null = null;
|
|
602
|
-
try {
|
|
603
|
-
delSelfRes = await commentClient.deleteSelfComment(
|
|
604
|
-
appId,
|
|
605
|
-
theme,
|
|
606
|
-
themeAuthor,
|
|
607
|
-
blockHeight || 0,
|
|
608
|
-
userPubkey.string(),
|
|
609
|
-
commentCid,
|
|
610
|
-
commentBlockHeightUint32,
|
|
611
|
-
signature,
|
|
612
|
-
);
|
|
613
|
-
} catch (error: any) {
|
|
614
|
-
delSelfError = new CommentError("deleteSelfComment error" + (error && error.message));
|
|
615
|
-
}
|
|
616
|
-
try {
|
|
617
|
-
delObjRes = await commentClient.deleteCommentToObj(
|
|
618
|
-
appId,
|
|
619
|
-
theme,
|
|
620
|
-
themeAuthor,
|
|
621
|
-
blockHeight || 0,
|
|
622
|
-
userPubkey.string(),
|
|
623
|
-
commentCid,
|
|
624
|
-
commentBlockHeightUint32,
|
|
625
|
-
signature,
|
|
626
|
-
);
|
|
627
|
-
} catch (error: any) {
|
|
628
|
-
delObjError = new CommentError("deleteCommentToObj error" + (error && error.message));
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
if(delSelfRes !== 0){
|
|
632
|
-
return [delSelfRes, delSelfError || new CommentError("deleteSelfComment error")];
|
|
633
|
-
}
|
|
634
|
-
if(delObjRes !== 0){
|
|
635
|
-
return [delObjRes, delObjError || new CommentError("deleteCommentToObj error")];
|
|
636
|
-
}
|
|
637
|
-
return [0, null];
|
|
638
|
-
} catch (err) {
|
|
639
|
-
console.error("deleteSelfComment error:", err);
|
|
640
|
-
throw err;
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
async getThemeObj(
|
|
645
|
-
appId: string,
|
|
646
|
-
themeAuthor: string,
|
|
647
|
-
startHeight: number,
|
|
648
|
-
direction: number,
|
|
649
|
-
offset: number,
|
|
650
|
-
limit: number,
|
|
651
|
-
seekKey: string,
|
|
652
|
-
): Promise<[ThemeObj[] | null, Error | null]> {
|
|
653
|
-
try {
|
|
654
|
-
if (!this.connectedDc?.client) {
|
|
655
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
656
|
-
}
|
|
657
|
-
if (!this.context.publicKey) {
|
|
658
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
659
|
-
}
|
|
660
|
-
let client = this.context.AccountBackupDc.client;
|
|
661
|
-
if (!client || themeAuthor != this.context.publicKey.string()) {//查询他人主题评论
|
|
662
|
-
const authorPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
663
|
-
const connectedClient = await this.dc.connectToUserDcPeer(authorPublicKey.raw);
|
|
664
|
-
if (!connectedClient) {
|
|
665
|
-
return [null, Errors.ErrNoPeerIdIsNull];
|
|
666
|
-
}
|
|
667
|
-
client = connectedClient;
|
|
668
|
-
}
|
|
669
|
-
if(client.token == ""){
|
|
670
|
-
await client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
671
|
-
}
|
|
672
|
-
const commentClient = new CommentClient(
|
|
673
|
-
client,
|
|
674
|
-
this.dcNodeClient,
|
|
675
|
-
this.context
|
|
676
|
-
);
|
|
677
|
-
|
|
678
|
-
const res = await commentClient.getThemeObj(
|
|
679
|
-
appId,
|
|
680
|
-
themeAuthor,
|
|
681
|
-
startHeight || 0,
|
|
682
|
-
direction || 0,
|
|
683
|
-
offset || 0,
|
|
684
|
-
limit || 0,
|
|
685
|
-
seekKey || '',
|
|
686
|
-
);
|
|
687
|
-
const fileManager = new FileManager(
|
|
688
|
-
this.dc,
|
|
689
|
-
this.connectedDc,
|
|
690
|
-
this.chainUtil,
|
|
691
|
-
this.dcNodeClient,
|
|
692
|
-
this.context
|
|
693
|
-
);
|
|
694
|
-
const cid = Buffer.from(res).toString();
|
|
695
|
-
const fileContent = await fileManager.getFileFromDc(
|
|
696
|
-
cid,
|
|
697
|
-
"",
|
|
698
|
-
cidNeedConnect.NOT_NEED,
|
|
699
|
-
false
|
|
700
|
-
);
|
|
701
|
-
if (!fileContent) {
|
|
702
|
-
return [[], null];
|
|
703
|
-
}
|
|
704
|
-
const fileContentString = uint8ArrayToString(fileContent);
|
|
705
|
-
const allContent = await this.handleThemeObj(fileContentString);
|
|
706
|
-
console.log("getThemeObj allContent:", allContent);
|
|
707
|
-
return [allContent, null];
|
|
708
|
-
} catch (err) {
|
|
709
|
-
console.error("getThemeObj error:", err);
|
|
710
|
-
throw err;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
async getThemeComments(
|
|
715
|
-
appId: string,
|
|
716
|
-
theme: string,
|
|
717
|
-
themeAuthor: string,
|
|
718
|
-
startHeight: number,
|
|
719
|
-
direction: number,
|
|
720
|
-
offset: number,
|
|
721
|
-
limit: number,
|
|
722
|
-
seekKey: string,
|
|
723
|
-
vaccount?: string,
|
|
724
|
-
): Promise<[ThemeComment[] | null, Error | null]> {
|
|
725
|
-
try {
|
|
726
|
-
if (!this.connectedDc?.client) {
|
|
727
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
728
|
-
}
|
|
729
|
-
if (!this.context.publicKey) {
|
|
730
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
731
|
-
}
|
|
732
|
-
let client = this.context.AccountBackupDc.client;
|
|
733
|
-
if (!client || themeAuthor != this.context.publicKey.string()) {//查询他人主题评论
|
|
734
|
-
const authorPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
735
|
-
const connectedClient = await this.dc.connectToUserDcPeer(authorPublicKey.raw);
|
|
736
|
-
if (!connectedClient) {
|
|
737
|
-
return [null, Errors.ErrNoPeerIdIsNull];
|
|
738
|
-
}
|
|
739
|
-
client = connectedClient;
|
|
740
|
-
}
|
|
741
|
-
if(client.token == ""){
|
|
742
|
-
await client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
743
|
-
}
|
|
744
|
-
const aesKey = SymmetricKey.new();// 生成aeskey文件加密密码
|
|
745
|
-
const commentClient = new CommentClient(
|
|
746
|
-
client,
|
|
747
|
-
this.dcNodeClient,
|
|
748
|
-
this.context
|
|
749
|
-
);
|
|
750
|
-
const res = await commentClient.getThemeComments(
|
|
751
|
-
appId,
|
|
752
|
-
theme,
|
|
753
|
-
themeAuthor,
|
|
754
|
-
startHeight || 0,
|
|
755
|
-
direction || 0,
|
|
756
|
-
offset || 0,
|
|
757
|
-
limit || 0,
|
|
758
|
-
seekKey || '',
|
|
759
|
-
aesKey ? aesKey.toString() : "",
|
|
760
|
-
vaccount,
|
|
761
|
-
);
|
|
762
|
-
if (!res) {
|
|
763
|
-
return [[], null];
|
|
764
|
-
}
|
|
765
|
-
const fileManager = new FileManager(
|
|
766
|
-
this.dc,
|
|
767
|
-
this.connectedDc,
|
|
768
|
-
this.chainUtil,
|
|
769
|
-
this.dcNodeClient,
|
|
770
|
-
this.context
|
|
771
|
-
);
|
|
772
|
-
const cid = Buffer.from(res).toString();
|
|
773
|
-
const fileContent = await fileManager.getFileFromDc(
|
|
774
|
-
cid,
|
|
775
|
-
"",
|
|
776
|
-
cidNeedConnect.NOT_NEED,
|
|
777
|
-
false
|
|
778
|
-
);
|
|
779
|
-
if (!fileContent) {
|
|
780
|
-
return [[], null];
|
|
781
|
-
}
|
|
782
|
-
const fileContentString = uint8ArrayToString(fileContent);
|
|
783
|
-
const allContent = await this.handleThemeComments(fileContentString, aesKey);
|
|
784
|
-
console.log("getThemeComments allContent:", allContent);
|
|
785
|
-
return [allContent || null, null];
|
|
786
|
-
} catch (err) {
|
|
787
|
-
console.error("getThemeComments error:", err);
|
|
788
|
-
throw err;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
async configAuth(
|
|
795
|
-
appId: string,
|
|
796
|
-
themeAuthor: string,
|
|
797
|
-
theme: string,
|
|
798
|
-
authPubkey: string,
|
|
799
|
-
permission: number,
|
|
800
|
-
remark: string,
|
|
801
|
-
vaccount?: string
|
|
802
|
-
): Promise<[number | null, Error | null]> {
|
|
803
|
-
if (!theme.endsWith("_authlist")) {
|
|
804
|
-
theme = theme + "_authlist";
|
|
805
|
-
}
|
|
806
|
-
if(!this.context.publicKey){
|
|
807
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
const userPubkey = this.context.publicKey;
|
|
811
|
-
let userPubkeyStr = userPubkey.string();
|
|
812
|
-
|
|
813
|
-
let client = this.context.AccountBackupDc.client;
|
|
814
|
-
if (themeAuthor != userPubkeyStr) {//查询他人主题评论
|
|
815
|
-
const authorPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
816
|
-
const connectedClient = await this.dc.connectToUserDcPeer(authorPublicKey.raw);
|
|
817
|
-
if (!connectedClient) {
|
|
818
|
-
return [null, Errors.ErrNoPeerIdIsNull];
|
|
819
|
-
}
|
|
820
|
-
client = connectedClient;
|
|
821
|
-
|
|
822
|
-
}
|
|
823
|
-
if (!client) {
|
|
824
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
if (client.peerAddr === null) {
|
|
828
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
829
|
-
}
|
|
830
|
-
if(client.token == ""){
|
|
831
|
-
await client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
832
|
-
}
|
|
833
|
-
const themeAuthorPubkey: Ed25519PubKey =
|
|
834
|
-
Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
835
|
-
|
|
836
|
-
let forPubkeyHex: string;
|
|
837
|
-
try {
|
|
838
|
-
const forPubkey = Ed25519PubKey.edPubkeyFromStr(authPubkey);
|
|
839
|
-
forPubkeyHex = forPubkey.string();
|
|
840
|
-
} catch (error) {
|
|
841
|
-
forPubkeyHex = authPubkey;
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
const content = `${forPubkeyHex}:${permission}:${remark}`;
|
|
845
|
-
|
|
846
|
-
// Generate contentCid (sha256 of content)
|
|
847
|
-
const commentUint8 = new TextEncoder().encode(content);
|
|
848
|
-
const contentHash = await sha256(commentUint8);
|
|
849
|
-
const contentCid = base32.encode(contentHash);
|
|
850
|
-
|
|
851
|
-
// Get blockchain height
|
|
852
|
-
let blockHeight: number;
|
|
853
|
-
try {
|
|
854
|
-
blockHeight = await this.chainUtil.getBlockHeight() || 0;
|
|
855
|
-
} catch (error) {
|
|
856
|
-
return [null, new Error("ErrGetBlockHeightFail")];
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
const contentSize = commentUint8.length;
|
|
860
|
-
|
|
861
|
-
// Create binary representation of blockHeight (little endian)
|
|
862
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
863
|
-
blockHeight ? blockHeight : 0
|
|
864
|
-
);
|
|
865
|
-
// Create binary representation of type (little endian)
|
|
866
|
-
const typeValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
867
|
-
CommentType.Comment
|
|
868
|
-
);
|
|
869
|
-
// sign(Theme+appId+objAuthor+blockheight+contentCid)
|
|
870
|
-
const themeValue: Uint8Array = new TextEncoder().encode(theme);
|
|
871
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
872
|
-
const themeAuthorValue: Uint8Array = new TextEncoder().encode(
|
|
873
|
-
themeAuthorPubkey.string()
|
|
874
|
-
);
|
|
875
|
-
const contentCidValue: Uint8Array = new TextEncoder().encode(contentCid);
|
|
876
|
-
let preSign = new Uint8Array([
|
|
877
|
-
...themeValue,
|
|
878
|
-
...appIdValue,
|
|
879
|
-
...themeAuthorValue,
|
|
880
|
-
...hValue,
|
|
881
|
-
...contentCidValue,
|
|
882
|
-
...typeValue,
|
|
883
|
-
]);
|
|
884
|
-
|
|
885
|
-
const signature = await this.context.sign(preSign);
|
|
886
|
-
|
|
887
|
-
const commentClient = new CommentClient(
|
|
888
|
-
client,
|
|
889
|
-
this.dcNodeClient,
|
|
890
|
-
this.context
|
|
891
|
-
);
|
|
892
|
-
try {
|
|
893
|
-
const res = await commentClient.configThemeObjAuth(
|
|
894
|
-
theme,
|
|
895
|
-
appId,
|
|
896
|
-
themeAuthor,
|
|
897
|
-
blockHeight,
|
|
898
|
-
userPubkeyStr,
|
|
899
|
-
contentCid,
|
|
900
|
-
content,
|
|
901
|
-
contentSize,
|
|
902
|
-
CommentType.Comment,
|
|
903
|
-
signature,
|
|
904
|
-
vaccount
|
|
905
|
-
);
|
|
906
|
-
|
|
907
|
-
if (res !== 0) {
|
|
908
|
-
return [res, new Error(`configThemeObjAuth fail, resFlag: ${res}`)];
|
|
909
|
-
}else {
|
|
910
|
-
return [0, null];
|
|
911
|
-
}
|
|
912
|
-
} catch (error: any) {
|
|
913
|
-
return [null, error];
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
async getAuthList(
|
|
919
|
-
appId: string,
|
|
920
|
-
themeAuthor: string,
|
|
921
|
-
theme: string,
|
|
922
|
-
vaccount?: string
|
|
923
|
-
): Promise<[ThemeAuthInfo[]|null,ThemeComment[] | null, Error | null]> {
|
|
924
|
-
if (!theme.endsWith("_authlist")) {
|
|
925
|
-
theme = theme + "_authlist";
|
|
926
|
-
}
|
|
927
|
-
let seekKey: string = "";
|
|
928
|
-
let originAuthList: ThemeComment[] = [];
|
|
929
|
-
let authList: ThemeAuthInfo[] = [];
|
|
930
|
-
try {
|
|
931
|
-
while (true) {
|
|
932
|
-
const commentManager = new CommentManager(this.context);
|
|
933
|
-
const res = await commentManager.getThemeComments(
|
|
934
|
-
appId,
|
|
935
|
-
theme,
|
|
936
|
-
themeAuthor,
|
|
937
|
-
0,
|
|
938
|
-
Direction.Forward,
|
|
939
|
-
0,
|
|
940
|
-
1000,
|
|
941
|
-
seekKey || "",
|
|
942
|
-
vaccount
|
|
943
|
-
);
|
|
944
|
-
if (res[0] && res[0].length == 0) {
|
|
945
|
-
return [authList,originAuthList, null];
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
const resList = res[0];
|
|
949
|
-
if (!resList || resList.length == 0) {
|
|
950
|
-
break;
|
|
951
|
-
}
|
|
952
|
-
for (let i = 0; i < resList.length; i++) {
|
|
953
|
-
originAuthList.push(resList[i]!);
|
|
954
|
-
const content = resList[i]!.comment
|
|
955
|
-
const parts = content.split(":");
|
|
956
|
-
if (parts.length < 2) {
|
|
957
|
-
continue;
|
|
958
|
-
}
|
|
959
|
-
const authPubkey = parts[0]!;
|
|
960
|
-
const permission = parseInt(parts[1]!);
|
|
961
|
-
const remark = content.substring(authPubkey.length + parts[1]!.length + 2);
|
|
962
|
-
authList.push({
|
|
963
|
-
pubkey: authPubkey,
|
|
964
|
-
permission: permission,
|
|
965
|
-
remark: remark,
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
if (resList.length < 1000) {
|
|
969
|
-
break;
|
|
970
|
-
}
|
|
971
|
-
seekKey = `${resList[resList.length - 1]!.blockheight}/${
|
|
972
|
-
resList[resList.length - 1]!.commentCid
|
|
973
|
-
}`;
|
|
974
|
-
}
|
|
975
|
-
} catch (error: any) {
|
|
976
|
-
return [authList,originAuthList, error];
|
|
977
|
-
}
|
|
978
|
-
return [authList,originAuthList, null];
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
async getUserComments(
|
|
982
|
-
appId: string,
|
|
983
|
-
userPubkey: string,
|
|
984
|
-
startHeight: number,
|
|
985
|
-
direction: number,
|
|
986
|
-
offset: number,
|
|
987
|
-
limit: number,
|
|
988
|
-
seekKey: string,
|
|
989
|
-
): Promise<[ThemeComment[] | null, Error | null]> {
|
|
990
|
-
try {
|
|
991
|
-
if (!this.connectedDc?.client) {
|
|
992
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
993
|
-
}
|
|
994
|
-
if(!this.context.publicKey){
|
|
995
|
-
return [null, Errors.ErrPublicKeyIsNull];
|
|
996
|
-
}
|
|
997
|
-
if(this.connectedDc.client.token == ""){
|
|
998
|
-
await this.connectedDc.client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
999
|
-
}
|
|
1000
|
-
let client = this.context.AccountBackupDc.client;
|
|
1001
|
-
if (userPubkey != this.context.publicKey.string()) {//查询他人主题评论
|
|
1002
|
-
const userPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(userPubkey);
|
|
1003
|
-
const connectedClient = await this.dc.connectToUserDcPeer(userPublicKey.raw);
|
|
1004
|
-
if (!connectedClient) {
|
|
1005
|
-
return [null, Errors.ErrNoPeerIdIsNull];
|
|
1006
|
-
}
|
|
1007
|
-
client = connectedClient;
|
|
1008
|
-
}
|
|
1009
|
-
if (!client) {
|
|
1010
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
1011
|
-
}
|
|
1012
|
-
if(client.token == ""){
|
|
1013
|
-
await client.GetToken(appId, this.context.publicKey.string(),this.context.sign);
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
const aesKey = SymmetricKey.new();// 生成aeskey文件加密密码
|
|
1017
|
-
const commentClient = new CommentClient(
|
|
1018
|
-
this.connectedDc.client,
|
|
1019
|
-
this.dcNodeClient,
|
|
1020
|
-
this.context
|
|
1021
|
-
);
|
|
1022
|
-
const res = await commentClient.getUserComments(
|
|
1023
|
-
appId,
|
|
1024
|
-
userPubkey,
|
|
1025
|
-
startHeight || 0,
|
|
1026
|
-
direction || 0,
|
|
1027
|
-
offset || 0,
|
|
1028
|
-
limit || 0,
|
|
1029
|
-
seekKey || '',
|
|
1030
|
-
aesKey ? aesKey.toString() : ''
|
|
1031
|
-
);
|
|
1032
|
-
if (!res) {
|
|
1033
|
-
return [[], null];
|
|
1034
|
-
}
|
|
1035
|
-
const fileManager = new FileManager(
|
|
1036
|
-
this.dc,
|
|
1037
|
-
this.connectedDc,
|
|
1038
|
-
this.chainUtil,
|
|
1039
|
-
this.dcNodeClient,
|
|
1040
|
-
this.context
|
|
1041
|
-
);
|
|
1042
|
-
const cid = Buffer.from(res).toString();
|
|
1043
|
-
const fileContent = await fileManager.getFileFromDc(
|
|
1044
|
-
cid,
|
|
1045
|
-
"",
|
|
1046
|
-
cidNeedConnect.NOT_NEED,
|
|
1047
|
-
false
|
|
1048
|
-
);
|
|
1049
|
-
console.log("getUserComments fileContent:", fileContent);
|
|
1050
|
-
if (!fileContent) {
|
|
1051
|
-
return [[], null];
|
|
1052
|
-
}
|
|
1053
|
-
const fileContentString = uint8ArrayToString(fileContent);
|
|
1054
|
-
const allContent = await this.handleThemeComments(fileContentString, aesKey);
|
|
1055
|
-
console.log("getUserComments allContent:", allContent);
|
|
1056
|
-
return [allContent || null, null];
|
|
1057
|
-
} catch (err) {
|
|
1058
|
-
console.error("getUserComments error:", err);
|
|
1059
|
-
throw err;
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
private handleThemeObj = async (fileContentString: string): Promise<ThemeObj[]> => {
|
|
1063
|
-
const reader = new BrowserLineReader(fileContentString);
|
|
1064
|
-
|
|
1065
|
-
let allContent: Array<ThemeObj> = [];
|
|
1066
|
-
// readLine 循环
|
|
1067
|
-
while (true) {
|
|
1068
|
-
const { line, error } = readLine(reader);
|
|
1069
|
-
if (error && error.message !== "EOF") {
|
|
1070
|
-
console.error("读取错误:", error);
|
|
1071
|
-
break;
|
|
1072
|
-
} else if (line) {
|
|
1073
|
-
// 将Uint8Array转回字符串
|
|
1074
|
-
const decoder = new TextDecoder();
|
|
1075
|
-
const lineString = decoder.decode(line);
|
|
1076
|
-
if (!lineString) {
|
|
1077
|
-
break;
|
|
1078
|
-
}
|
|
1079
|
-
const fileContentUint8Array = base32.decode(lineString);
|
|
1080
|
-
const content = dcnet.pb.AddThemeObjRequest.decode(
|
|
1081
|
-
fileContentUint8Array
|
|
1082
|
-
);
|
|
1083
|
-
allContent.push({
|
|
1084
|
-
theme: uint8ArrayToString(content.theme),
|
|
1085
|
-
appId: uint8ArrayToString(content.appId),
|
|
1086
|
-
blockheight: content.blockheight,
|
|
1087
|
-
commentSpace: content.commentSpace,
|
|
1088
|
-
allowSpace: content.allowSpace,
|
|
1089
|
-
userPubkey: uint8ArrayToString(content.userPubkey),
|
|
1090
|
-
openFlag: content.openFlag,
|
|
1091
|
-
signature: bytesToHex(content.signature),
|
|
1092
|
-
CCount: content.CCount,
|
|
1093
|
-
UpCount: content.UpCount,
|
|
1094
|
-
DownCount: content.DownCount,
|
|
1095
|
-
TCount: content.TCount,
|
|
1096
|
-
vaccount: uint8ArrayToString(content.vaccount),
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
return allContent;
|
|
1101
|
-
};
|
|
1102
|
-
private handleThemeComments = async (fileContentString: string, aesKey: SymmetricKey): Promise<ThemeComment[]> => {
|
|
1103
|
-
const reader = new BrowserLineReader(fileContentString);
|
|
1104
|
-
let allContent: Array<ThemeComment> = [];
|
|
1105
|
-
|
|
1106
|
-
if (!this.context.getPublicKey()) {
|
|
1107
|
-
return [];
|
|
1108
|
-
}
|
|
1109
|
-
// readLine 循环
|
|
1110
|
-
while (true) {
|
|
1111
|
-
const { line, error } = readLine(reader);
|
|
1112
|
-
if (error && error.message !== "EOF") {
|
|
1113
|
-
console.error("读取错误:", error);
|
|
1114
|
-
break;
|
|
1115
|
-
} else if (line) {
|
|
1116
|
-
// 将Uint8Array转回字符串
|
|
1117
|
-
const decoder = new TextDecoder();
|
|
1118
|
-
const lineString = decoder.decode(line);
|
|
1119
|
-
if (!lineString) {
|
|
1120
|
-
break;
|
|
1121
|
-
}
|
|
1122
|
-
const lineContent = base32.decode(lineString);
|
|
1123
|
-
const plainContent = await aesKey.decrypt(lineContent);
|
|
1124
|
-
const content =
|
|
1125
|
-
dcnet.pb.PublishCommentToThemeRequest.decode(plainContent);
|
|
1126
|
-
|
|
1127
|
-
allContent.push({
|
|
1128
|
-
theme: uint8ArrayToString(content.theme),
|
|
1129
|
-
appId: uint8ArrayToString(content.appId),
|
|
1130
|
-
themeAuthor: uint8ArrayToString(content.themeAuthor),
|
|
1131
|
-
blockheight: content.blockheight,
|
|
1132
|
-
userPubkey: uint8ArrayToString(content.userPubkey),
|
|
1133
|
-
commentCid: uint8ArrayToString(content.commentCid),
|
|
1134
|
-
comment: uint8ArrayToString(content.comment),
|
|
1135
|
-
commentSize: content.commentSize,
|
|
1136
|
-
status: content.status,
|
|
1137
|
-
refercommentkey: uint8ArrayToString(content.refercommentkey),
|
|
1138
|
-
CCount: content.CCount,
|
|
1139
|
-
UpCount: content.UpCount,
|
|
1140
|
-
DownCount: content.DownCount,
|
|
1141
|
-
TCount: content.TCount,
|
|
1142
|
-
type: content.type,
|
|
1143
|
-
signature: bytesToHex(content.signature),
|
|
1144
|
-
vaccount: bytesToHex(content.vaccount),
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
return allContent;
|
|
1149
|
-
};
|
|
1150
|
-
}
|
|
1151
|
-
|