web-dc-api 0.0.87 → 0.0.89
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 -0
- package/dist/cjs/protobuf-BVBdi7Hh.js +1 -0
- package/dist/dc.min.js +1 -19
- package/dist/esm/chunks/protobuf-CbxDm-Gy.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +947 -886
- package/package.json +14 -17
- package/dist/index.cjs.js +0 -19
- package/dist/index.esm.js +0 -19
- 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 -595
- package/lib/common/define.ts +0 -66
- 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 -694
- 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 -202
- 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 -443
- package/lib/implements/threaddb/dbmanager.ts +0 -1901
- package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -452
- 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 -280
- 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 -138
- package/lib/implements/threaddb/net/grpcClient.ts +0 -582
- package/lib/implements/threaddb/net/grpcserver.ts +0 -146
- package/lib/implements/threaddb/net/net.ts +0 -2006
- 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 -664
- 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/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/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,670 +0,0 @@
|
|
|
1
|
-
import type { Multiaddr } from "@multiformats/multiaddr";
|
|
2
|
-
import { AIProxyConfig, DCConnectInfo, OnStreamResponseType, ProxyCallConfig, ThemeComment, UserProxyCallConfig } from "../../common/types/types";
|
|
3
|
-
import { AIProxyUserPermission, cidNeedConnect, OpenFlag } from "../../common/constants";
|
|
4
|
-
import { CommentManager } from "../comment/manager";
|
|
5
|
-
import { HeliaLibp2p } from "helia";
|
|
6
|
-
import { ChainUtil } from "../../common/chain";
|
|
7
|
-
import { DcUtil } from "../../common/dcutil";
|
|
8
|
-
import { Ed25519PubKey } from "../../common/dc-key/ed25519";
|
|
9
|
-
import { sha256, uint32ToLittleEndianBytes } from "../../util/utils";
|
|
10
|
-
import { base32 } from "multiformats/bases/base32";
|
|
11
|
-
import { Client } from "../../common/dcapi";
|
|
12
|
-
import { CommentType, Direction } from "../../common/define";
|
|
13
|
-
import { DCContext } from "../../../lib/interfaces/DCContext";
|
|
14
|
-
import { AIProxyClient } from "./client";
|
|
15
|
-
import { FileManager } from "../file/manager";
|
|
16
|
-
import { toString as uint8ArrayToString } from "uint8arrays/to-string";
|
|
17
|
-
import { BrowserLineReader, readLine } from "../../util/BrowserLineReader";
|
|
18
|
-
import { dcnet } from "../../proto/dcnet_proto";
|
|
19
|
-
import { bytesToHex } from "@noble/curves/abstract/utils";
|
|
20
|
-
import { KeyValueClient } from "../keyvalue/client";
|
|
21
|
-
import { SymmetricKey } from "../threaddb/common/key";
|
|
22
|
-
import { Libp2p } from "@libp2p/interface";
|
|
23
|
-
|
|
24
|
-
// 错误定义
|
|
25
|
-
export class AIProxyError extends Error {
|
|
26
|
-
constructor(message: string) {
|
|
27
|
-
super(message);
|
|
28
|
-
this.name = "AIProxyError";
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
export const Errors = {
|
|
32
|
-
ErrNoDcPeerConnected: new AIProxyError("no dc peer connected"),
|
|
33
|
-
ErrKeyNotValid: new AIProxyError("key not valid"),
|
|
34
|
-
// nodeAddr is null
|
|
35
|
-
ErrNodeAddrIsNull: new AIProxyError("nodeAddr is null"),
|
|
36
|
-
// chainUtil is null
|
|
37
|
-
ErrChainUtilIsNull: new AIProxyError("chainUtil is null"),
|
|
38
|
-
// account privatekey sign is null
|
|
39
|
-
ErrAccountPrivateSignIsNull: new AIProxyError("account privatekey sign is null"),
|
|
40
|
-
// account publickey is null
|
|
41
|
-
ErrAccountPublicKeyIsNull: new AIProxyError("account publickey is null"),
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
export class AIProxyManager {
|
|
50
|
-
private dc: DcUtil;
|
|
51
|
-
private dcNodeClient: HeliaLibp2p<Libp2p>;
|
|
52
|
-
private chainUtil: ChainUtil;
|
|
53
|
-
private context: DCContext;
|
|
54
|
-
constructor(
|
|
55
|
-
dc: DcUtil,
|
|
56
|
-
dcNodeClient: HeliaLibp2p<Libp2p>,
|
|
57
|
-
chainUtil: ChainUtil,
|
|
58
|
-
context: DCContext
|
|
59
|
-
) {
|
|
60
|
-
this.dc = dc;
|
|
61
|
-
this.dcNodeClient = dcNodeClient;
|
|
62
|
-
this.chainUtil = chainUtil;
|
|
63
|
-
this.context = context;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// 创建AI调用的Proxy配置
|
|
67
|
-
async createProxyConfig(
|
|
68
|
-
appId: string,
|
|
69
|
-
configTheme: string,
|
|
70
|
-
): Promise<[number | null, Error | null]> {
|
|
71
|
-
// Default group to "DCAPP" if empty
|
|
72
|
-
if (appId === "") {
|
|
73
|
-
appId = "DCAPP";
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const space = 100 << 20;
|
|
77
|
-
// Theme must start with "keyvalue_"
|
|
78
|
-
if (!configTheme.startsWith("keyvalue_")) {
|
|
79
|
-
configTheme = "keyvalue_" + configTheme;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
// Assuming AddThemeObjDeal is implemented elsewhere
|
|
84
|
-
const commentManager = new CommentManager(this.context);
|
|
85
|
-
const res = await commentManager.addThemeObj(
|
|
86
|
-
appId,
|
|
87
|
-
configTheme,
|
|
88
|
-
OpenFlag.AUTH,
|
|
89
|
-
space
|
|
90
|
-
);
|
|
91
|
-
return res;
|
|
92
|
-
} catch (error) {
|
|
93
|
-
return [null, error as Error];
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// 删除AI调用的Proxy配置
|
|
100
|
-
async deleteProxyConfig(
|
|
101
|
-
appId: string,
|
|
102
|
-
configTheme: string,
|
|
103
|
-
): Promise<[number | null, Error | null]> {
|
|
104
|
-
// Default group to "DCAPP" if empty
|
|
105
|
-
if (appId === "") {
|
|
106
|
-
appId = "DCAPP";
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Theme must start with "keyvalue_"
|
|
110
|
-
if (!configTheme.startsWith("keyvalue_")) {
|
|
111
|
-
configTheme = "keyvalue_" + configTheme;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
const commentManager = new CommentManager(this.context);
|
|
116
|
-
const res = await commentManager.deleteThemeObj(
|
|
117
|
-
appId,
|
|
118
|
-
configTheme
|
|
119
|
-
);
|
|
120
|
-
return res;
|
|
121
|
-
} catch (error) {
|
|
122
|
-
return [null, error as Error];
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
//配置AI代理的访问配置,如果key的值设置为空,则表示删除该key的配置
|
|
129
|
-
async configAIProxy(
|
|
130
|
-
appId: string,
|
|
131
|
-
configAuthor: string,
|
|
132
|
-
configTheme: string,
|
|
133
|
-
serviceName: string,
|
|
134
|
-
serviceConfig?: AIProxyConfig,
|
|
135
|
-
vaccount?: string
|
|
136
|
-
): Promise<[boolean | null, Error | null]> {
|
|
137
|
-
if(!this.context.publicKey) {
|
|
138
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
139
|
-
}
|
|
140
|
-
const blockHeight: number = await this.chainUtil.getBlockHeight() || 0;
|
|
141
|
-
const userPubkey = this.context.getPublicKey();
|
|
142
|
-
let userPubkeyStr = userPubkey.string();
|
|
143
|
-
if (!configTheme.startsWith("keyvalue_")) {
|
|
144
|
-
configTheme = "keyvalue_" + configTheme;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
let client = this.context.AccountBackupDc?.client || null;
|
|
148
|
-
if (!client){
|
|
149
|
-
client = await this.dc.connectToUserDcPeer(this.context.publicKey.raw);
|
|
150
|
-
}
|
|
151
|
-
if (!client) {
|
|
152
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
153
|
-
}
|
|
154
|
-
//获取token
|
|
155
|
-
await client.GetToken(
|
|
156
|
-
this.context.appInfo.appId || "",
|
|
157
|
-
this.context.publicKey.string(),
|
|
158
|
-
this.context.sign
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (client === null) {
|
|
163
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
164
|
-
}
|
|
165
|
-
if (client.token == "") {
|
|
166
|
-
await client.GetToken(
|
|
167
|
-
this.context.appInfo.appId || "",
|
|
168
|
-
this.context.publicKey.string(),
|
|
169
|
-
this.context.sign
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
let content = '';
|
|
174
|
-
const key = serviceName
|
|
175
|
-
if (!serviceConfig) {
|
|
176
|
-
content = `${key}`;
|
|
177
|
-
}else{
|
|
178
|
-
serviceConfig.blockheight = blockHeight;
|
|
179
|
-
const value = JSON.stringify(serviceConfig)
|
|
180
|
-
content = `${key}:${value}`;
|
|
181
|
-
}
|
|
182
|
-
const contentUint8 = new TextEncoder().encode(content);
|
|
183
|
-
const contenthash = await sha256(contentUint8);
|
|
184
|
-
const contentCidBase32 = base32.encode(contenthash);
|
|
185
|
-
|
|
186
|
-
const contentSize = contentUint8.length;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
190
|
-
blockHeight ? blockHeight : 0
|
|
191
|
-
);
|
|
192
|
-
const themeValue: Uint8Array = new TextEncoder().encode(configTheme);
|
|
193
|
-
const themeAuthorValue: Uint8Array = new TextEncoder().encode(configAuthor);
|
|
194
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
195
|
-
const contentCidValue: Uint8Array = new TextEncoder().encode(
|
|
196
|
-
contentCidBase32
|
|
197
|
-
);
|
|
198
|
-
const typeValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
199
|
-
CommentType.KeyValue
|
|
200
|
-
);
|
|
201
|
-
const preSign = new Uint8Array([
|
|
202
|
-
...themeValue,
|
|
203
|
-
...appIdValue,
|
|
204
|
-
...themeAuthorValue,
|
|
205
|
-
...hValue,
|
|
206
|
-
...contentCidValue,
|
|
207
|
-
...typeValue,
|
|
208
|
-
]);
|
|
209
|
-
const signature = await this.context.sign(preSign);
|
|
210
|
-
const keyValueClient = new KeyValueClient(client, this.context);
|
|
211
|
-
try {
|
|
212
|
-
const [resFlag,_] = await keyValueClient.setKeyValue(
|
|
213
|
-
configTheme,
|
|
214
|
-
appId,
|
|
215
|
-
configAuthor,
|
|
216
|
-
blockHeight,
|
|
217
|
-
userPubkeyStr,
|
|
218
|
-
contentCidBase32,
|
|
219
|
-
content,
|
|
220
|
-
contentSize,
|
|
221
|
-
CommentType.KeyValue,
|
|
222
|
-
signature,
|
|
223
|
-
vaccount
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
if (resFlag !== 0) {
|
|
227
|
-
return [null, new Error(`configAIProxy fail, resFlag:${resFlag}`)];
|
|
228
|
-
}
|
|
229
|
-
return [true, null];
|
|
230
|
-
} catch (error) {
|
|
231
|
-
return [false, error as Error];
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
//配置用户的访问权限
|
|
238
|
-
async configAuth(
|
|
239
|
-
appId: string,
|
|
240
|
-
configAuthor: string,
|
|
241
|
-
configTheme: string,
|
|
242
|
-
authPubkey: string,
|
|
243
|
-
permission: AIProxyUserPermission,
|
|
244
|
-
authConfig: ProxyCallConfig,
|
|
245
|
-
vaccount?: string
|
|
246
|
-
): Promise<[number | null, Error | null]> {
|
|
247
|
-
if(!this.context.publicKey) {
|
|
248
|
-
return [null, Errors.ErrAccountPublicKeyIsNull];
|
|
249
|
-
}
|
|
250
|
-
if (!configTheme.startsWith("keyvalue_")) {
|
|
251
|
-
configTheme = "keyvalue_" + configTheme;
|
|
252
|
-
}
|
|
253
|
-
if (!configTheme.endsWith("_authlist")) {
|
|
254
|
-
configTheme = configTheme + "_authlist";
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const userPubkey = this.context.getPublicKey();
|
|
258
|
-
let userPubkeyStr = userPubkey.string();
|
|
259
|
-
|
|
260
|
-
let client = this.context.AccountBackupDc?.client || null;
|
|
261
|
-
if (!client){
|
|
262
|
-
client = await this.dc.connectToUserDcPeer(this.context.publicKey.raw);
|
|
263
|
-
}
|
|
264
|
-
if (client === null) {
|
|
265
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (client.peerAddr === null) {
|
|
269
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
270
|
-
}
|
|
271
|
-
if (client.token == "") {
|
|
272
|
-
await client.GetToken(
|
|
273
|
-
this.context.appInfo.appId || "",
|
|
274
|
-
this.context.publicKey.string(),
|
|
275
|
-
this.context.sign
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const themeAuthorPubkey: Ed25519PubKey =
|
|
280
|
-
Ed25519PubKey.edPubkeyFromStr(configAuthor);
|
|
281
|
-
|
|
282
|
-
let pubkeyFlag = true;
|
|
283
|
-
let forPubkey: Ed25519PubKey | null = null;
|
|
284
|
-
try {
|
|
285
|
-
forPubkey = Ed25519PubKey.edPubkeyFromStr(authPubkey);
|
|
286
|
-
} catch (error) {
|
|
287
|
-
pubkeyFlag = false;
|
|
288
|
-
}
|
|
289
|
-
let forPubkeyHex: string;
|
|
290
|
-
if (pubkeyFlag && forPubkey) {
|
|
291
|
-
forPubkeyHex = forPubkey.string();
|
|
292
|
-
} else {
|
|
293
|
-
forPubkeyHex = authPubkey;
|
|
294
|
-
}
|
|
295
|
-
//将authConfig转换为字符串
|
|
296
|
-
const remark = JSON.stringify(authConfig);
|
|
297
|
-
const content = `${forPubkeyHex}:${permission}:${remark}`;
|
|
298
|
-
|
|
299
|
-
// Generate contentCid (sha256 of content)
|
|
300
|
-
const commentUint8 = new TextEncoder().encode(content);
|
|
301
|
-
const contentHash = await sha256(commentUint8);
|
|
302
|
-
const contentCid = base32.encode(contentHash);
|
|
303
|
-
|
|
304
|
-
// Get blockchain height
|
|
305
|
-
let blockHeight: number;
|
|
306
|
-
try {
|
|
307
|
-
blockHeight = await this.chainUtil.getBlockHeight() || 0;
|
|
308
|
-
} catch (error) {
|
|
309
|
-
return [null, new Error("ErrGetBlockHeightFail")];
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const contentSize = commentUint8.length;
|
|
313
|
-
|
|
314
|
-
// Create binary representation of blockHeight (little endian)
|
|
315
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
316
|
-
blockHeight ? blockHeight : 0
|
|
317
|
-
);
|
|
318
|
-
// Create binary representation of type (little endian)
|
|
319
|
-
const typeValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
320
|
-
CommentType.Comment
|
|
321
|
-
);
|
|
322
|
-
// sign(Theme+appId+objAuthor+blockheight+contentCid)
|
|
323
|
-
const themeValue: Uint8Array = new TextEncoder().encode(configTheme);
|
|
324
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
325
|
-
const themeAuthorValue: Uint8Array = new TextEncoder().encode(
|
|
326
|
-
themeAuthorPubkey.string()
|
|
327
|
-
);
|
|
328
|
-
const contentCidValue: Uint8Array = new TextEncoder().encode(contentCid);
|
|
329
|
-
let preSign = new Uint8Array([
|
|
330
|
-
...themeValue,
|
|
331
|
-
...appIdValue,
|
|
332
|
-
...themeAuthorValue,
|
|
333
|
-
...hValue,
|
|
334
|
-
...contentCidValue,
|
|
335
|
-
...typeValue,
|
|
336
|
-
]);
|
|
337
|
-
|
|
338
|
-
const signature = await this.context.sign(preSign);
|
|
339
|
-
|
|
340
|
-
const keyValueClient = new KeyValueClient(client, this.context);
|
|
341
|
-
try {
|
|
342
|
-
const res = await keyValueClient.configThemeObjAuth(
|
|
343
|
-
configTheme,
|
|
344
|
-
appId,
|
|
345
|
-
configAuthor,
|
|
346
|
-
blockHeight,
|
|
347
|
-
userPubkeyStr,
|
|
348
|
-
contentCid,
|
|
349
|
-
content,
|
|
350
|
-
contentSize,
|
|
351
|
-
CommentType.Comment,
|
|
352
|
-
signature
|
|
353
|
-
);
|
|
354
|
-
|
|
355
|
-
if (res !== 0) {
|
|
356
|
-
return [null, new Error(`configThemeObjAuth fail, resFlag: ${res}`)];
|
|
357
|
-
}
|
|
358
|
-
} catch (error) {
|
|
359
|
-
return [null, error as Error];
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
return [0, null];
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
//获取的ai代理的所有配置,包括服务与授权列表
|
|
366
|
-
async GetAIProxyConfig(
|
|
367
|
-
appId: string,
|
|
368
|
-
themeAuthor: string,
|
|
369
|
-
configTheme: string,
|
|
370
|
-
vaccount?: string
|
|
371
|
-
): Promise<[UserProxyCallConfig[] | null,AIProxyConfig[] | null, Error | null]> {
|
|
372
|
-
if(!this.context.publicKey) {
|
|
373
|
-
return [null,null, Errors.ErrAccountPublicKeyIsNull];
|
|
374
|
-
}
|
|
375
|
-
if (!configTheme.startsWith("keyvalue_")) {
|
|
376
|
-
configTheme = "keyvalue_" + configTheme;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
let client = this.context.AccountBackupDc.client || null;
|
|
383
|
-
if (themeAuthor != this.context.publicKey.string()) {//查询他人主题评论
|
|
384
|
-
const authorPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
385
|
-
client = await this.dc.connectToUserDcPeer(authorPublicKey.raw);
|
|
386
|
-
if (!client) {
|
|
387
|
-
return [null,null, Errors.ErrNoDcPeerConnected];
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
if (client === null) {
|
|
391
|
-
return [null,null, new Error("ErrConnectToAccountPeersFail")];
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (client.peerAddr === null) {
|
|
395
|
-
return [null,null, new Error("ErrConnectToAccountPeersFail")];
|
|
396
|
-
}
|
|
397
|
-
if (client.token == "") {
|
|
398
|
-
await client.GetToken(
|
|
399
|
-
this.context.appInfo.appId || "",
|
|
400
|
-
this.context.publicKey.string(),
|
|
401
|
-
this.context.sign
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
try {
|
|
405
|
-
const aiProxyClient = new AIProxyClient(client, this.context);
|
|
406
|
-
const [proxyConfigCid, aesKey, error] = await aiProxyClient.GetAIProxyConfig(
|
|
407
|
-
appId,
|
|
408
|
-
themeAuthor,
|
|
409
|
-
configTheme
|
|
410
|
-
)
|
|
411
|
-
if (error) {
|
|
412
|
-
return [null,null, error];
|
|
413
|
-
}
|
|
414
|
-
const fileManager = new FileManager(
|
|
415
|
-
this.dc,
|
|
416
|
-
this.context.AccountBackupDc,
|
|
417
|
-
this.chainUtil,
|
|
418
|
-
this.dcNodeClient,
|
|
419
|
-
this.context
|
|
420
|
-
);
|
|
421
|
-
const cid = proxyConfigCid;
|
|
422
|
-
const fileContent = await fileManager.getFileFromDc(
|
|
423
|
-
cid,
|
|
424
|
-
"",
|
|
425
|
-
cidNeedConnect.NOT_NEED,
|
|
426
|
-
false
|
|
427
|
-
);
|
|
428
|
-
if (!fileContent) {
|
|
429
|
-
return [[],[], null];
|
|
430
|
-
}
|
|
431
|
-
const fileContentString = uint8ArrayToString(fileContent);
|
|
432
|
-
const result = await this.handleAllConfig(fileContentString, aesKey);
|
|
433
|
-
if (!result) {
|
|
434
|
-
return [[], [], null];
|
|
435
|
-
}
|
|
436
|
-
const [allAuth, allContent] = result;
|
|
437
|
-
return [allAuth, allContent, null];
|
|
438
|
-
|
|
439
|
-
} catch (error) {
|
|
440
|
-
return [null, null, error as Error];
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
private handleAllConfig = async (fileContentString: string,aesKey:string): Promise<[UserProxyCallConfig[],AIProxyConfig[]] | null> => {
|
|
446
|
-
const reader = new BrowserLineReader(fileContentString);
|
|
447
|
-
let allContent: Array<AIProxyConfig> = [];
|
|
448
|
-
let allAuth: Array<UserProxyCallConfig> = [];
|
|
449
|
-
|
|
450
|
-
if (!this.context.getPublicKey()) {
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
453
|
-
const decryptKey = SymmetricKey.fromString(aesKey);
|
|
454
|
-
// readLine 循环
|
|
455
|
-
while (true) {
|
|
456
|
-
const { line, error } = readLine(reader);
|
|
457
|
-
if (error && error.message !== "EOF") {
|
|
458
|
-
console.error("读取错误:", error);
|
|
459
|
-
break;
|
|
460
|
-
} else if (line) {
|
|
461
|
-
// 将Uint8Array转回字符串
|
|
462
|
-
const decoder = new TextDecoder();
|
|
463
|
-
const lineString = decoder.decode(line);
|
|
464
|
-
if (!lineString) {
|
|
465
|
-
break;
|
|
466
|
-
}
|
|
467
|
-
const lineContent = base32.decode(lineString);
|
|
468
|
-
const plainContent = await decryptKey.decrypt(lineContent);
|
|
469
|
-
const contentStr = new TextDecoder().decode(plainContent);
|
|
470
|
-
if (!contentStr) {
|
|
471
|
-
continue; // 如果内容为空,跳过
|
|
472
|
-
}
|
|
473
|
-
if (contentStr.startsWith("$$auth$$:")) { //授权信息
|
|
474
|
-
try {
|
|
475
|
-
const authContent = contentStr.split("$$auth$$:")[1];
|
|
476
|
-
if (!authContent ) {
|
|
477
|
-
console.error("无效的授权信息格式:", contentStr);
|
|
478
|
-
continue; // 如果格式不正确,跳过
|
|
479
|
-
}
|
|
480
|
-
const parts = authContent.split(":");
|
|
481
|
-
if (parts.length < 2) {
|
|
482
|
-
console.error("无效的授权信息格式:", authContent);
|
|
483
|
-
continue; // 如果格式不正确,跳过
|
|
484
|
-
}
|
|
485
|
-
//解析出userpubkey
|
|
486
|
-
const userPubkey = parts[0] || "";
|
|
487
|
-
const permission = parts[1] || "";
|
|
488
|
-
const authContentStr = authContent.substring(
|
|
489
|
-
userPubkey.length + permission.length + 2 // +2 for the colon and the next colon
|
|
490
|
-
);
|
|
491
|
-
//解析到ProxyCallConfig结构
|
|
492
|
-
const authConfig = JSON.parse(authContentStr);
|
|
493
|
-
allAuth.push({
|
|
494
|
-
UserPubkey: userPubkey,
|
|
495
|
-
permission: parseInt(permission), //转成数字
|
|
496
|
-
authConfig: authConfig,
|
|
497
|
-
});
|
|
498
|
-
} catch (error) {
|
|
499
|
-
console.error("解析授权信息错误:", error);
|
|
500
|
-
}
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
//keyvalue中取出value
|
|
504
|
-
const parts: string[] = contentStr.split(":");
|
|
505
|
-
if (parts.length < 2) {
|
|
506
|
-
console.error("无效的内容格式:", contentStr);
|
|
507
|
-
continue; // 如果格式不正确,跳过
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
const valueWithExtra = contentStr.substring((parts[0]||"").length + 1);
|
|
511
|
-
try {
|
|
512
|
-
//解析出扩展信息(时间戳,用户公钥等)
|
|
513
|
-
const valueParts = valueWithExtra.split("$$$dckv_extra$$$");
|
|
514
|
-
const value = valueParts[0] || "{}";
|
|
515
|
-
const content = JSON.parse(value);
|
|
516
|
-
if (valueParts.length > 1) {
|
|
517
|
-
const extraStr = valueParts[1] || "{}";
|
|
518
|
-
const extra = JSON.parse(extraStr);
|
|
519
|
-
if (extra) {
|
|
520
|
-
if (extra.dc_timestamp) {
|
|
521
|
-
content.timestamp = extra.dc_timestamp;
|
|
522
|
-
}
|
|
523
|
-
if (extra.dc_opuser) {
|
|
524
|
-
content.userPubkey = extra.dc_opuser;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
allContent.push(content as AIProxyConfig);
|
|
529
|
-
} catch (error) {
|
|
530
|
-
console.error("解析内容错误:", error);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
return [allAuth, allContent] as [Array<UserProxyCallConfig>, Array<AIProxyConfig>];
|
|
535
|
-
};
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
async GetUserOwnAIProxyAuth(
|
|
539
|
-
appId: string,
|
|
540
|
-
themeAuthor: string,
|
|
541
|
-
configTheme: string,
|
|
542
|
-
): Promise<[authConfig: ProxyCallConfig | null, error: Error | null]> {
|
|
543
|
-
if(!this.context.publicKey) {
|
|
544
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
545
|
-
}
|
|
546
|
-
if( !configTheme.startsWith("keyvalue_")) {
|
|
547
|
-
configTheme = "keyvalue_" + configTheme;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
let client = this.context.AccountBackupDc?.client || null;
|
|
551
|
-
if (themeAuthor != this.context.publicKey.string()) {//查询他人主题评论
|
|
552
|
-
const authorPublicKey: Ed25519PubKey = Ed25519PubKey.edPubkeyFromStr(themeAuthor);
|
|
553
|
-
client = await this.dc.connectToUserDcPeer(authorPublicKey.raw);
|
|
554
|
-
if (!client) {
|
|
555
|
-
return [null, Errors.ErrNoDcPeerConnected];
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
if (client === null) {
|
|
560
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
if (client.peerAddr === null) {
|
|
564
|
-
return [null, new Error("ErrConnectToAccountPeersFail")];
|
|
565
|
-
}
|
|
566
|
-
if (client.token == "") {
|
|
567
|
-
await client.GetToken(
|
|
568
|
-
this.context.appInfo.appId || "",
|
|
569
|
-
this.context.publicKey.string(),
|
|
570
|
-
this.context.sign
|
|
571
|
-
);
|
|
572
|
-
}
|
|
573
|
-
const aiProxyClient = new AIProxyClient(client, this.context);
|
|
574
|
-
const [authInfo, error] = await aiProxyClient.GetUserOwnAIProxyAuth(
|
|
575
|
-
appId,
|
|
576
|
-
themeAuthor,
|
|
577
|
-
configTheme
|
|
578
|
-
);
|
|
579
|
-
if (error) {
|
|
580
|
-
return [null, error];
|
|
581
|
-
}
|
|
582
|
-
try {
|
|
583
|
-
const authConfig = JSON.parse(authInfo);
|
|
584
|
-
return [authConfig, error];
|
|
585
|
-
}catch (error:any) {
|
|
586
|
-
return [null, error];
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
//AI相关代理的调用,包括代理与AI的通信或者与MCPServer的通信
|
|
591
|
-
async DoAIProxyCall(
|
|
592
|
-
context: { signal?: AbortSignal },
|
|
593
|
-
appId: string,
|
|
594
|
-
themeAuthor: string,
|
|
595
|
-
configTheme: string,
|
|
596
|
-
serviceName: string,
|
|
597
|
-
reqBody: string,
|
|
598
|
-
forceRefresh: boolean,
|
|
599
|
-
onStreamResponse: OnStreamResponseType | null = null ,
|
|
600
|
-
headers?: string,
|
|
601
|
-
path?: string,
|
|
602
|
-
model?: string): Promise< number>
|
|
603
|
-
{
|
|
604
|
-
if( !configTheme.startsWith("keyvalue_")) {
|
|
605
|
-
configTheme = "keyvalue_" + configTheme;
|
|
606
|
-
}
|
|
607
|
-
const blockHeight = (await this.chainUtil.getBlockHeight()) || 0;
|
|
608
|
-
const hValue: Uint8Array = uint32ToLittleEndianBytes(
|
|
609
|
-
blockHeight ? blockHeight : 0
|
|
610
|
-
);
|
|
611
|
-
const forceRefreshFlag = forceRefresh ? 1 : 0;
|
|
612
|
-
const forceRefreshValue: Uint8Array = uint32ToLittleEndianBytes(forceRefreshFlag);
|
|
613
|
-
const themeAuthorValue: Uint8Array = new TextEncoder().encode(themeAuthor);
|
|
614
|
-
const themeValue: Uint8Array = new TextEncoder().encode(configTheme);
|
|
615
|
-
const appIdValue: Uint8Array = new TextEncoder().encode(appId);
|
|
616
|
-
const serviceNameValue: Uint8Array = new TextEncoder().encode(serviceName);
|
|
617
|
-
const pathValue: Uint8Array = new TextEncoder().encode(path);
|
|
618
|
-
const headersValue: Uint8Array = new TextEncoder().encode(headers);
|
|
619
|
-
const reqBodyValue: Uint8Array = new TextEncoder().encode(reqBody);
|
|
620
|
-
const modelValue: Uint8Array = new TextEncoder().encode(model);
|
|
621
|
-
const preSign = new Uint8Array([
|
|
622
|
-
...themeValue,
|
|
623
|
-
...appIdValue,
|
|
624
|
-
...themeAuthorValue,
|
|
625
|
-
...hValue,
|
|
626
|
-
...serviceNameValue,
|
|
627
|
-
...pathValue,
|
|
628
|
-
...reqBodyValue,
|
|
629
|
-
...forceRefreshValue,
|
|
630
|
-
...modelValue,
|
|
631
|
-
...headersValue
|
|
632
|
-
]);
|
|
633
|
-
if (!this.context.AccountBackupDc.client) {
|
|
634
|
-
throw new Error("ErrConnectToAccountPeersFail");
|
|
635
|
-
}
|
|
636
|
-
if(!this.context.publicKey){
|
|
637
|
-
throw new Error("ErrConnectToAccountPeersFail");
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
if (this.context.AccountBackupDc.client.token == "") {
|
|
641
|
-
await this.context.AccountBackupDc.client.GetToken(
|
|
642
|
-
this.context.appInfo.appId || "",
|
|
643
|
-
this.context.publicKey.string(),
|
|
644
|
-
this.context.sign
|
|
645
|
-
);
|
|
646
|
-
}
|
|
647
|
-
const signature = await this.context.sign(preSign);
|
|
648
|
-
const proxyClient = new AIProxyClient(
|
|
649
|
-
this.context.AccountBackupDc.client,
|
|
650
|
-
this.context
|
|
651
|
-
);
|
|
652
|
-
let res = await proxyClient.DoAIProxyCall(
|
|
653
|
-
context,
|
|
654
|
-
appId,
|
|
655
|
-
themeAuthor,
|
|
656
|
-
configTheme,
|
|
657
|
-
serviceName,
|
|
658
|
-
path || "",
|
|
659
|
-
headers || "",
|
|
660
|
-
reqBody,
|
|
661
|
-
model || "",
|
|
662
|
-
forceRefreshFlag,
|
|
663
|
-
blockHeight ,
|
|
664
|
-
signature,
|
|
665
|
-
onStreamResponse
|
|
666
|
-
);
|
|
667
|
-
return res;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|