web-dc-api 0.1.5 → 0.1.7
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,753 +0,0 @@
|
|
|
1
|
-
// modules/auth-module.ts
|
|
2
|
-
// 认证功能模块
|
|
3
|
-
|
|
4
|
-
import { DCModule, CoreModuleName } from "../common/module-system";
|
|
5
|
-
import { AccountManager } from "../implements/account/manager";
|
|
6
|
-
import { CommonClient } from "../common/commonclient";
|
|
7
|
-
import { Client } from "../common/dcapi";
|
|
8
|
-
import { createLogger } from "../util/logger";
|
|
9
|
-
import { sleep } from "../util/utils";
|
|
10
|
-
import { Ed25519PrivKey, Ed25519PubKey } from "../common/dc-key/ed25519";
|
|
11
|
-
import { Errors } from "../common/error";
|
|
12
|
-
import {
|
|
13
|
-
dc_protocol,
|
|
14
|
-
OffChainOpTimes,
|
|
15
|
-
OffChainOpTimesLimit,
|
|
16
|
-
OffChainSpaceLimit,
|
|
17
|
-
} from "../common/define";
|
|
18
|
-
import { Multiaddr } from "@multiformats/multiaddr";
|
|
19
|
-
import { WalletManager } from "../implements/wallet/manager";
|
|
20
|
-
import {
|
|
21
|
-
Account,
|
|
22
|
-
AccountInfo,
|
|
23
|
-
EIP712SignReqMessage,
|
|
24
|
-
NFTBindStatus,
|
|
25
|
-
SignReqMessage,
|
|
26
|
-
SignResponseMessage,
|
|
27
|
-
User,
|
|
28
|
-
} from "../common/types/types";
|
|
29
|
-
import { IAuthOperations } from "../interfaces/auth-interface";
|
|
30
|
-
import { DCContext } from "../../lib/interfaces/DCContext";
|
|
31
|
-
import { CommentManager } from "../../lib/implements/comment/manager";
|
|
32
|
-
|
|
33
|
-
const logger = createLogger("AuthModule");
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 认证模块
|
|
37
|
-
* 处理用户登录、Token管理等功能
|
|
38
|
-
*/
|
|
39
|
-
export class AuthModule implements DCModule, IAuthOperations {
|
|
40
|
-
readonly moduleName = CoreModuleName.AUTH;
|
|
41
|
-
private context!: DCContext;
|
|
42
|
-
private initialized: boolean = false;
|
|
43
|
-
private tokenTask: boolean = false;
|
|
44
|
-
private walletManager!: WalletManager;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* 初始化认证模块
|
|
48
|
-
* @param context DC上下文
|
|
49
|
-
* @returns 是否初始化成功
|
|
50
|
-
*/
|
|
51
|
-
async initialize(context: DCContext): Promise<boolean> {
|
|
52
|
-
this.context = context;
|
|
53
|
-
// 启动异步初始化任务,不等待其完成
|
|
54
|
-
(async () => {
|
|
55
|
-
try {
|
|
56
|
-
logger.info("真正的认证模块初始化开始");
|
|
57
|
-
const walletManager = new WalletManager(this.context);
|
|
58
|
-
this.walletManager = walletManager;
|
|
59
|
-
await walletManager.init();
|
|
60
|
-
this.initialized = true;
|
|
61
|
-
logger.info("真正的认证模块初始化完成");
|
|
62
|
-
} catch (error) {
|
|
63
|
-
logger.error("真正的认证模块初始化失败:", error);
|
|
64
|
-
this.initialized = false;
|
|
65
|
-
}
|
|
66
|
-
})();
|
|
67
|
-
// 立即返回
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* 关闭认证模块
|
|
73
|
-
*/
|
|
74
|
-
async shutdown(): Promise<void> {
|
|
75
|
-
// 停止Token维护任务
|
|
76
|
-
this.stopTokenKeepValidTask();
|
|
77
|
-
this.initialized = false;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 账户登录
|
|
82
|
-
* @returns 是否登录成功
|
|
83
|
-
*/
|
|
84
|
-
async accountLoginWithWalletCall(accountInfo: AccountInfo = {} as AccountInfo): Promise<Account | null> {
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
this.assertInitialized();
|
|
88
|
-
|
|
89
|
-
if (!this.context.connectedDc?.client) {
|
|
90
|
-
throw new Error("dcClient is null");
|
|
91
|
-
}
|
|
92
|
-
const data = await this.walletManager.openConnect(accountInfo);
|
|
93
|
-
// 登录成功,清空临时私钥
|
|
94
|
-
this.context.privateKey = null;
|
|
95
|
-
// 如果有返回则保存到context中
|
|
96
|
-
if(data && data.accountInfo && data.accountInfo.nftAccount) {
|
|
97
|
-
this.context.accountInfo = data.accountInfo;
|
|
98
|
-
}
|
|
99
|
-
const publicKey = new Ed25519PubKey(data.appAccount);
|
|
100
|
-
this.context.publicKey = publicKey;
|
|
101
|
-
this.context.ethAddress = data.ethAccount;
|
|
102
|
-
// 获取token
|
|
103
|
-
const token = await this.context.connectedDc?.client.GetToken(
|
|
104
|
-
this.context.appInfo.appId || "",
|
|
105
|
-
publicKey.string(),
|
|
106
|
-
(payload: Uint8Array): Promise<Uint8Array> => {
|
|
107
|
-
return this.signWithWallet(payload);
|
|
108
|
-
}
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
if (!token) {
|
|
112
|
-
throw new Error("GetToken error");
|
|
113
|
-
}
|
|
114
|
-
// 存在token, 获取用户备用节点
|
|
115
|
-
await this.getAccountBackupDc();
|
|
116
|
-
if (this.context.AccountBackupDc?.client) {//备份节点存在,获取备份节点连接的token
|
|
117
|
-
// 获取账号备用节点token
|
|
118
|
-
await this.context.AccountBackupDc?.client.GetToken(
|
|
119
|
-
this.context.appInfo.appId || "",
|
|
120
|
-
publicKey.string(),
|
|
121
|
-
(payload: Uint8Array): Promise<Uint8Array> => {
|
|
122
|
-
return this.signWithWallet(payload);
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// 给用户添加用户评论空间
|
|
128
|
-
const [userInfo, err] = await this.getUserInfoWithAccount(
|
|
129
|
-
"0x" + publicKey.toString()
|
|
130
|
-
);
|
|
131
|
-
if (err) {
|
|
132
|
-
throw err;
|
|
133
|
-
}
|
|
134
|
-
if (userInfo == null) {
|
|
135
|
-
throw Errors.USER_NOT_BIND_TO_PEER;
|
|
136
|
-
}
|
|
137
|
-
//获取用户已经使用的评论空间和操作次数
|
|
138
|
-
const commentManager = new CommentManager(this.context);
|
|
139
|
-
const [offchainUsedInfo,resErr] = await commentManager.getUserOffChainUsedInfo()
|
|
140
|
-
if (resErr) {
|
|
141
|
-
throw resErr;
|
|
142
|
-
}
|
|
143
|
-
const leftSpace = offchainUsedInfo?userInfo.offchainSpace - Number(offchainUsedInfo.usedspace) :userInfo.offchainSpace;
|
|
144
|
-
const leftOptimes = offchainUsedInfo?userInfo.offchainOptimes - Number(offchainUsedInfo.usedtimes):userInfo.offchainOptimes;
|
|
145
|
-
logger.info(
|
|
146
|
-
`用户线下评论空间剩余: ${leftSpace} / ${userInfo.offchainSpace}, 线下操作次数剩余: ${leftOptimes} / ${userInfo.offchainOptimes}`
|
|
147
|
-
);
|
|
148
|
-
if (leftSpace < OffChainSpaceLimit || leftOptimes < OffChainOpTimesLimit) {
|
|
149
|
-
if (leftSpace < OffChainSpaceLimit) {
|
|
150
|
-
const [addOffChainBool, addOffChainError] = await commentManager.addUserOffChainSpace();
|
|
151
|
-
if (addOffChainError || !addOffChainBool) {
|
|
152
|
-
throw addOffChainError || new Error("addUserOffChainSpace error");
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (leftOptimes < OffChainOpTimesLimit) {
|
|
156
|
-
const [addOffChainOpTimesBool, addOffChainOpTimesError] =await commentManager.addUserOffChainOpTimes(OffChainOpTimes);
|
|
157
|
-
if (addOffChainOpTimesError || !addOffChainOpTimesBool) {
|
|
158
|
-
throw (
|
|
159
|
-
addOffChainOpTimesError || new Error("addUserOffChainSpace error")
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return data;
|
|
165
|
-
} catch (error) {
|
|
166
|
-
console.error("accountLogin error", error);
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 账户登录(钱包登录)不抛出异常
|
|
173
|
-
* @returns [账户信息, 错误信息]
|
|
174
|
-
*/
|
|
175
|
-
async accountLoginWithWallet(accountInfo?:AccountInfo): Promise<
|
|
176
|
-
[Account | null, Error | null]
|
|
177
|
-
> {
|
|
178
|
-
try {
|
|
179
|
-
const account = await this.accountLoginWithWalletCall(accountInfo);
|
|
180
|
-
this.context.userInfo = account;
|
|
181
|
-
return [account, null];
|
|
182
|
-
} catch (error) {
|
|
183
|
-
return [null, error as Error];
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
exitLogin (): void {
|
|
188
|
-
this.walletManager.exitLogin();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* 账户登录(钱包登录)不抛出异常
|
|
193
|
-
* @param nftAccount NFT账户
|
|
194
|
-
* @param password 密码
|
|
195
|
-
* @param safecode 安全码
|
|
196
|
-
* @returns [是否登录成功, 错误信息]
|
|
197
|
-
*/
|
|
198
|
-
async accountLogin(
|
|
199
|
-
nftAccount: string,
|
|
200
|
-
password: string,
|
|
201
|
-
safecode: string
|
|
202
|
-
): Promise<[string, Error | null]> {
|
|
203
|
-
try {
|
|
204
|
-
this.assertInitialized();
|
|
205
|
-
|
|
206
|
-
if (!this.context.connectedDc?.client) {
|
|
207
|
-
throw new Error("dcClient is null");
|
|
208
|
-
}
|
|
209
|
-
//连接account所在的节点,并获取client
|
|
210
|
-
let client = this.context.connectedDc?.client || null;
|
|
211
|
-
const walletAccount = await this.context.dcChain?.getUserWalletAccount(
|
|
212
|
-
nftAccount
|
|
213
|
-
);
|
|
214
|
-
if (!walletAccount) {
|
|
215
|
-
throw new Error("getUserWalletAccount error");
|
|
216
|
-
}
|
|
217
|
-
const userPubkey: Ed25519PubKey =
|
|
218
|
-
Ed25519PubKey.edPubkeyFromStr(walletAccount);
|
|
219
|
-
const connectedClient = await this.context.dcutil.connectToUserDcPeer(
|
|
220
|
-
userPubkey.raw
|
|
221
|
-
);
|
|
222
|
-
if (!connectedClient) {
|
|
223
|
-
throw new Error("connect to user dc peer failed");
|
|
224
|
-
}
|
|
225
|
-
client = connectedClient;
|
|
226
|
-
this.context.AccountBackupDc.client = client;
|
|
227
|
-
const commonClient = new CommonClient(client);
|
|
228
|
-
const mnemonic = await commonClient.accountLogin(
|
|
229
|
-
nftAccount,
|
|
230
|
-
password,
|
|
231
|
-
safecode
|
|
232
|
-
);
|
|
233
|
-
console.log("=================accountLogin success");
|
|
234
|
-
|
|
235
|
-
if (mnemonic) {
|
|
236
|
-
// 登录成功,清空临时私钥
|
|
237
|
-
this.context.privateKey = null;
|
|
238
|
-
this.context.publicKey = undefined;
|
|
239
|
-
//清空原来连接的token信息,原来是基于临时私钥登录的
|
|
240
|
-
client.token = "";
|
|
241
|
-
this.context.connectedDc.client.token = "";
|
|
242
|
-
|
|
243
|
-
if (this.context.appInfo?.appId) {
|
|
244
|
-
const accountManager = new AccountManager(this.context);
|
|
245
|
-
|
|
246
|
-
const res = await accountManager.generateAppAccount(
|
|
247
|
-
this.context.appInfo?.appId,
|
|
248
|
-
mnemonic
|
|
249
|
-
);
|
|
250
|
-
console.log("=================generateAppAccount success");
|
|
251
|
-
if (res[0] === null) {
|
|
252
|
-
throw res[1] || new Error("generateAppAccount error");
|
|
253
|
-
}
|
|
254
|
-
// 获取私钥
|
|
255
|
-
const privKey = Ed25519PrivKey.unmarshalString(res[0]);
|
|
256
|
-
console.log("=================获取私钥 success");
|
|
257
|
-
}
|
|
258
|
-
this.context.userInfo = {
|
|
259
|
-
nftAccount, // NFT账号
|
|
260
|
-
appAccount:userPubkey.raw, // 应用专用账号公钥
|
|
261
|
-
ethAccount:'', // 以太坊兼容链上账号
|
|
262
|
-
chainId:'', // 区块链ID
|
|
263
|
-
chainName:'', // 区块链名称
|
|
264
|
-
}
|
|
265
|
-
return [mnemonic, null];
|
|
266
|
-
}
|
|
267
|
-
return ["", new Error("accountLogin failed")];
|
|
268
|
-
} catch (error) {
|
|
269
|
-
return ["", error as Error];
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
async signWithWallet(payload: Uint8Array): Promise<Uint8Array> {
|
|
274
|
-
if (!this.walletManager) {
|
|
275
|
-
throw new Error("walletManager is null");
|
|
276
|
-
} else {
|
|
277
|
-
if (!this.context.privateKey) {
|
|
278
|
-
// 登录过
|
|
279
|
-
const signature = await this.walletManager.sign(payload);
|
|
280
|
-
return signature;
|
|
281
|
-
}
|
|
282
|
-
const signature = this.context.privateKey?.sign(payload) as Uint8Array;
|
|
283
|
-
return signature;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
async sign(payload: Uint8Array): Promise<[Uint8Array | null, Error | null]> {
|
|
288
|
-
try {
|
|
289
|
-
const signature = await this.signWithWallet(payload);
|
|
290
|
-
return [signature, null];
|
|
291
|
-
} catch (error) {
|
|
292
|
-
return [null, error as Error];
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
async decryptWithWallet(
|
|
297
|
-
payload: Uint8Array
|
|
298
|
-
): Promise<[Uint8Array | null, Error | null]> {
|
|
299
|
-
try {
|
|
300
|
-
if (!this.walletManager) {
|
|
301
|
-
throw new Error("walletManager is null");
|
|
302
|
-
}
|
|
303
|
-
const signature = await this.walletManager.decrypt(payload);
|
|
304
|
-
return [signature, null];
|
|
305
|
-
} catch (error) {
|
|
306
|
-
return [null, error as Error];
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
async signMessageWithWallet(
|
|
311
|
-
data: SignReqMessage
|
|
312
|
-
): Promise<SignResponseMessage | null> {
|
|
313
|
-
if (!this.walletManager) {
|
|
314
|
-
throw new Error("walletManager is null");
|
|
315
|
-
} else {
|
|
316
|
-
const response = await this.walletManager.signMessage(data);
|
|
317
|
-
return response;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
async signEIP712MessageWithWallet(
|
|
322
|
-
data: EIP712SignReqMessage
|
|
323
|
-
): Promise<SignResponseMessage | null> {
|
|
324
|
-
if (!this.walletManager) {
|
|
325
|
-
throw new Error("walletManager is null");
|
|
326
|
-
} else {
|
|
327
|
-
const response = await this.walletManager.signEIP712Message(data);
|
|
328
|
-
return response;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* 将私钥绑定NFT账号(NFT账号+密码+安全码)
|
|
333
|
-
* @param account NFT账号
|
|
334
|
-
* @param password 密码
|
|
335
|
-
* @param seccode 安全码
|
|
336
|
-
* @returns [状态码, 错误信息]
|
|
337
|
-
*/
|
|
338
|
-
async bindNFTAccount(
|
|
339
|
-
account: string,
|
|
340
|
-
password: string,
|
|
341
|
-
seccode: string,
|
|
342
|
-
mnemonic: string
|
|
343
|
-
): Promise<[NFTBindStatus | null, Error | null]> {
|
|
344
|
-
try {
|
|
345
|
-
this.assertInitialized();
|
|
346
|
-
|
|
347
|
-
if (!this.context.connectedDc?.client) {
|
|
348
|
-
throw new Error("dcClient is null");
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const accountManager = new AccountManager(this.context);
|
|
352
|
-
const res = await accountManager.bindNFTAccount(
|
|
353
|
-
account,
|
|
354
|
-
password,
|
|
355
|
-
seccode,
|
|
356
|
-
mnemonic
|
|
357
|
-
);
|
|
358
|
-
return [res[0], null];
|
|
359
|
-
} catch (error) {
|
|
360
|
-
return [null, error as Error];
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* 创建子账号,只有带有助记词的用户才能创建子账号
|
|
366
|
-
* 子账号创建后,用助记词登陆子账号App,与调用登陆了主账号的App进行授权登陆,是同一个用户
|
|
367
|
-
*
|
|
368
|
-
* @param appId 应用ID
|
|
369
|
-
* @returns [私钥字符串, 错误]
|
|
370
|
-
*/
|
|
371
|
-
async generateAppAccount(
|
|
372
|
-
appId: string,
|
|
373
|
-
mnemonic: string
|
|
374
|
-
): Promise<[string | null, Error | null]> {
|
|
375
|
-
try {
|
|
376
|
-
this.assertInitialized();
|
|
377
|
-
const accountManager = new AccountManager(this.context);
|
|
378
|
-
const [pubKeyStr, err] = await accountManager.generateAppAccount(appId, mnemonic);
|
|
379
|
-
if(err !== null) {
|
|
380
|
-
return [null, err];
|
|
381
|
-
}
|
|
382
|
-
return [pubKeyStr, null];
|
|
383
|
-
} catch (error) {
|
|
384
|
-
return [null, error as Error];
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* 检查NFT账号是否成功绑定到用户的公钥
|
|
391
|
-
* @param nftAccount NFT账号
|
|
392
|
-
* @param pubKeyStr 公钥字符串
|
|
393
|
-
* @returns 是否成功绑定
|
|
394
|
-
*/
|
|
395
|
-
async isNftAccountBindSuccess(
|
|
396
|
-
nftAccount: string,
|
|
397
|
-
pubKeyStr: string
|
|
398
|
-
): Promise<[boolean | null, Error | null]> {
|
|
399
|
-
try {
|
|
400
|
-
this.assertInitialized();
|
|
401
|
-
const accountManager = new AccountManager(this.context);
|
|
402
|
-
const res = await accountManager.isNftAccountBindSuccess(
|
|
403
|
-
nftAccount,
|
|
404
|
-
pubKeyStr
|
|
405
|
-
);
|
|
406
|
-
return [res, null];
|
|
407
|
-
} catch (error) {
|
|
408
|
-
return [null, error as Error];
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* 检查NFT账号是否已经被绑定
|
|
414
|
-
* @param nftAccount NFT账号
|
|
415
|
-
* @returns 是否被其他账号绑定
|
|
416
|
-
*/
|
|
417
|
-
async isNftAccountBinded(nftAccount: string): Promise<[boolean | null, Error | null]> {
|
|
418
|
-
try {
|
|
419
|
-
this.assertInitialized();
|
|
420
|
-
const accountManager = new AccountManager(this.context);
|
|
421
|
-
const res = await accountManager.isNftAccountBinded(nftAccount);
|
|
422
|
-
return [res, null];
|
|
423
|
-
} catch (error) {
|
|
424
|
-
return [null, error as Error];
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// 获取用户钱包信息,不抛出异常
|
|
429
|
-
async getUserInfoWithAccount(
|
|
430
|
-
account: string
|
|
431
|
-
): Promise<[User | null, Error | null]> {
|
|
432
|
-
try {
|
|
433
|
-
this.assertInitialized();
|
|
434
|
-
const res = await this.context.dcChain.getUserInfoWithAccount(account);
|
|
435
|
-
return [res, null];
|
|
436
|
-
} catch (error) {
|
|
437
|
-
return [null, error as Error];
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* 获取用户备用节点
|
|
443
|
-
*/
|
|
444
|
-
public async getAccountBackupDc(): Promise<void> {
|
|
445
|
-
// 存在token, 获取用户备用节点
|
|
446
|
-
const accountManager = new AccountManager(this.context);
|
|
447
|
-
|
|
448
|
-
const reply = await accountManager.getAccountNodeAddr();
|
|
449
|
-
if (reply && reply[0]) {
|
|
450
|
-
const nodeAddr = reply[0];
|
|
451
|
-
this.context.AccountBackupDc.nodeAddr = nodeAddr; // 当前地址
|
|
452
|
-
this.context.AccountBackupDc.client = await this.newDcClient(nodeAddr);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* 创建新的DC客户端
|
|
458
|
-
* @param nodeAddr 节点地址
|
|
459
|
-
* @returns DC客户端实例
|
|
460
|
-
*/
|
|
461
|
-
private async newDcClient(nodeAddr: Multiaddr): Promise<Client | undefined> {
|
|
462
|
-
if (!nodeAddr) {
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
const dcClient = new Client(
|
|
467
|
-
this.context.dcNodeClient.libp2p,
|
|
468
|
-
this.context.dcNodeClient.blockstore,
|
|
469
|
-
nodeAddr,
|
|
470
|
-
dc_protocol
|
|
471
|
-
);
|
|
472
|
-
|
|
473
|
-
return dcClient;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* 开启定时验证 token 线程,不抛出异常
|
|
478
|
-
*/
|
|
479
|
-
async startDcPeerTokenKeepValidTask(): Promise<
|
|
480
|
-
[boolean, Error | null]
|
|
481
|
-
> {
|
|
482
|
-
try {
|
|
483
|
-
this.assertInitialized();
|
|
484
|
-
|
|
485
|
-
// 如果已经有定时任务在跑,直接返回
|
|
486
|
-
if (this.tokenTask) {
|
|
487
|
-
return [true, null];
|
|
488
|
-
}
|
|
489
|
-
this.tokenTask = true;
|
|
490
|
-
|
|
491
|
-
// 60秒一次心跳维持连接
|
|
492
|
-
const period = 60*1000;
|
|
493
|
-
let count = 0;
|
|
494
|
-
let waitCount = 0;
|
|
495
|
-
|
|
496
|
-
// 启动ticker
|
|
497
|
-
logger.info("开始定时验证Token有效性任务");
|
|
498
|
-
(async () => {
|
|
499
|
-
while (this.tokenTask) {
|
|
500
|
-
waitCount ++;
|
|
501
|
-
try {
|
|
502
|
-
if (this.context.connectedDc.client?.token == "" || waitCount >= 300) {
|
|
503
|
-
await this.getTokenWithDCConnectInfo(this.context.connectedDc);
|
|
504
|
-
}
|
|
505
|
-
if (this.context.AccountBackupDc.client?.token == "" || waitCount >= 300) {
|
|
506
|
-
await this.getTokenWithDCConnectInfo(this.context.AccountBackupDc);
|
|
507
|
-
}
|
|
508
|
-
if (waitCount >= 300) {
|
|
509
|
-
waitCount = 0;
|
|
510
|
-
count++;
|
|
511
|
-
}
|
|
512
|
-
console.log(`第${count}次Token验证完成`);
|
|
513
|
-
|
|
514
|
-
} catch (error) {
|
|
515
|
-
logger.error("Token验证任务执行失败:", error);
|
|
516
|
-
}
|
|
517
|
-
await sleep(period);
|
|
518
|
-
}
|
|
519
|
-
})();
|
|
520
|
-
return [true, null];
|
|
521
|
-
} catch (error) {
|
|
522
|
-
return [false, error as Error];
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* 停止token验证任务,不抛出异常
|
|
528
|
-
*/
|
|
529
|
-
private stopTokenKeepValidTask(): void {
|
|
530
|
-
this.tokenTask = false;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
/**
|
|
534
|
-
* 获取或刷新指定连接信息的Token
|
|
535
|
-
* @param connectInfo 连接信息
|
|
536
|
-
*/
|
|
537
|
-
private async getTokenWithDCConnectInfo(connectInfo: any): Promise<void> {
|
|
538
|
-
|
|
539
|
-
try {
|
|
540
|
-
this.assertInitialized();
|
|
541
|
-
// 判断 client 是否为空
|
|
542
|
-
if (!connectInfo.client) {
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// 判断 client 是否连接,不连接则需要连接
|
|
547
|
-
if (
|
|
548
|
-
!connectInfo.client?.p2pNode ||
|
|
549
|
-
connectInfo.client?.p2pNode.status !== "started"
|
|
550
|
-
) {
|
|
551
|
-
try {
|
|
552
|
-
const nodeAddr = connectInfo.client?.peerAddr;
|
|
553
|
-
if (!nodeAddr) {
|
|
554
|
-
logger.error("nodeAddr is null");
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
logger.info("重新创建DC客户端");
|
|
558
|
-
connectInfo.client = await this.newDcClient(nodeAddr);
|
|
559
|
-
} catch (e) {
|
|
560
|
-
logger.error("重新连接失败", e);
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
} catch (error) {
|
|
565
|
-
logger.error("连接检查失败", error);
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// 判断 token 是否为空
|
|
570
|
-
if (!connectInfo.client?.token) {
|
|
571
|
-
try {
|
|
572
|
-
// 直接获取token
|
|
573
|
-
if (!this.context.publicKey) {
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
logger.info("获取新Token");
|
|
577
|
-
await connectInfo.client?.GetToken(
|
|
578
|
-
this.context.appInfo.appId || "",
|
|
579
|
-
this.context.publicKey.string(),
|
|
580
|
-
this.context.sign
|
|
581
|
-
);
|
|
582
|
-
return;
|
|
583
|
-
} catch (error) {
|
|
584
|
-
logger.error("获取token失败", error);
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
// 调用 ValidToken
|
|
590
|
-
try {
|
|
591
|
-
logger.debug("验证Token有效性");
|
|
592
|
-
await connectInfo.client?.ValidToken();
|
|
593
|
-
} catch (err: any) {
|
|
594
|
-
// 若 token 无效,需要刷新;否则重连
|
|
595
|
-
if (err?.message && err.message.endsWith(Errors.INVALID_TOKEN.message)) {
|
|
596
|
-
if (!this.context.publicKey) {
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
logger.info("刷新Token");
|
|
600
|
-
await connectInfo.client?.refreshToken(
|
|
601
|
-
this.context.appInfo.appId || "",
|
|
602
|
-
this.context.publicKey.string(),
|
|
603
|
-
this.context.sign
|
|
604
|
-
);
|
|
605
|
-
} else {
|
|
606
|
-
logger.info("需要重连节点");
|
|
607
|
-
// 需要重连
|
|
608
|
-
let resClient: Client | undefined;
|
|
609
|
-
try {
|
|
610
|
-
const nodeAddr = await this.context.dcutil?._getNodeAddr(
|
|
611
|
-
connectInfo.nodeAddr?.getPeerId() as string
|
|
612
|
-
);
|
|
613
|
-
if (!nodeAddr) {
|
|
614
|
-
logger.error("无法获取节点地址");
|
|
615
|
-
return;
|
|
616
|
-
}
|
|
617
|
-
resClient = await this.newDcClient(nodeAddr);
|
|
618
|
-
if (!resClient) {
|
|
619
|
-
logger.error("创建客户端失败");
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
} catch (e: any) {
|
|
623
|
-
logger.error(
|
|
624
|
-
`获取客户端失败, err: ${
|
|
625
|
-
e?.message
|
|
626
|
-
}, PEERID: ${connectInfo.nodeAddr?.getPeerId()}`
|
|
627
|
-
);
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
if (resClient) {
|
|
632
|
-
connectInfo.client = resClient;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
try {
|
|
636
|
-
// 直接获取token
|
|
637
|
-
if (!this.context.publicKey) {
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
logger.info("获取新Token");
|
|
641
|
-
await connectInfo.client?.GetToken(
|
|
642
|
-
this.context.appInfo.appId || "",
|
|
643
|
-
this.context.publicKey.string(),
|
|
644
|
-
this.context.sign
|
|
645
|
-
);
|
|
646
|
-
} catch (tokenErr: any) {
|
|
647
|
-
logger.error(
|
|
648
|
-
`获取token失败, err: ${
|
|
649
|
-
tokenErr?.message
|
|
650
|
-
}, PEERID: ${connectInfo.nodeAddr?.getPeerId()}`
|
|
651
|
-
);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
/**
|
|
657
|
-
* 获取用户信息
|
|
658
|
-
* @param nftAccount NFT账户
|
|
659
|
-
* @returns 用户信息
|
|
660
|
-
*/
|
|
661
|
-
async getUserInfoWithNft(
|
|
662
|
-
nftAccount: string
|
|
663
|
-
): Promise<[User | null, Error | null]> {
|
|
664
|
-
try {
|
|
665
|
-
this.assertInitialized();
|
|
666
|
-
|
|
667
|
-
const accountManager = new AccountManager(this.context);
|
|
668
|
-
|
|
669
|
-
const res = await accountManager.getUserInfoWithNft(nftAccount);
|
|
670
|
-
logger.info("获取用户信息成功:", res);
|
|
671
|
-
return res;
|
|
672
|
-
} catch (error) {
|
|
673
|
-
return [null, error as Error];
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
/**
|
|
678
|
-
* 检查用户空间是否足够,不抛出异常
|
|
679
|
-
* @param needSize 需要的空间大小
|
|
680
|
-
* @returns [是否足够, 错误信息]
|
|
681
|
-
*/
|
|
682
|
-
async ifEnoughUserSpace(
|
|
683
|
-
needSize?: number
|
|
684
|
-
): Promise<[boolean | null, Error | null]> {
|
|
685
|
-
try {
|
|
686
|
-
this.assertInitialized();
|
|
687
|
-
|
|
688
|
-
const pubkeyRaw = this.context.getPubkeyRaw();
|
|
689
|
-
const res = await this.context.dcChain.ifEnoughUserSpace(pubkeyRaw, needSize);
|
|
690
|
-
return [res, null];
|
|
691
|
-
} catch (error) {
|
|
692
|
-
return [null, error as Error];
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
/**
|
|
697
|
-
* 刷新用户信息,不抛出异常
|
|
698
|
-
* @returns [用户信息, 错误信息]
|
|
699
|
-
*/
|
|
700
|
-
async refreshUserInfo(): Promise<[User | null, Error | null]> {
|
|
701
|
-
try {
|
|
702
|
-
this.assertInitialized();
|
|
703
|
-
|
|
704
|
-
const pubkeyRaw = this.context.getPubkeyRaw();
|
|
705
|
-
if (!pubkeyRaw) {
|
|
706
|
-
throw new Error("用户未登录!");
|
|
707
|
-
}
|
|
708
|
-
const res = await this.context.dcChain.refreshUserInfo(pubkeyRaw);
|
|
709
|
-
return [res, null];
|
|
710
|
-
} catch (error) {
|
|
711
|
-
return [null, error as Error];
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
/**
|
|
717
|
-
* 获取用户默认数据库,不抛出异常
|
|
718
|
-
* @param threadId 数据库ID
|
|
719
|
-
* @param rk 读取密钥,主要用来加解密真正的数据,注意对数据记录进行加密和解密
|
|
720
|
-
* @param sk 服务密钥,主要用来处理传输过程加解密,主要对数据链表头进行加密和解密
|
|
721
|
-
* @param remark 备注信息
|
|
722
|
-
* @returns [用户默认数据库信息, 错误信息]
|
|
723
|
-
*/
|
|
724
|
-
async setUserDefaultDB(
|
|
725
|
-
threadId: string,
|
|
726
|
-
rk: string,
|
|
727
|
-
sk: string,
|
|
728
|
-
remark: string,
|
|
729
|
-
vaccount?: string
|
|
730
|
-
): Promise<Error | null> {
|
|
731
|
-
try {
|
|
732
|
-
this.assertInitialized();
|
|
733
|
-
const accountManager = new AccountManager(this.context);
|
|
734
|
-
await accountManager.setUserDefaultDB(threadId, rk, sk, remark, vaccount);
|
|
735
|
-
return null;
|
|
736
|
-
} catch (error) {
|
|
737
|
-
return error as Error;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/**
|
|
742
|
-
* 断言模块已初始化
|
|
743
|
-
*/
|
|
744
|
-
private async assertInitialized(timeoutMs = 30000): Promise<void> {
|
|
745
|
-
const start = Date.now();
|
|
746
|
-
while (!this.initialized) {
|
|
747
|
-
if (Date.now() - start > timeoutMs) {
|
|
748
|
-
throw new Error("认证模块未初始化(超时)");
|
|
749
|
-
}
|
|
750
|
-
await new Promise(res => setTimeout(res, 100)); // 每 100ms 检查一次
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
}
|