web-dc-api 0.0.83 → 0.0.85

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.
@@ -22,7 +22,7 @@ const walletOpenVersion =
22
22
  let _baseUrl = "";
23
23
  let _walletOrigin = "";
24
24
  if (true) {
25
- _baseUrl = "/v0_0_13";
25
+ _baseUrl = "/v0_0_14";
26
26
  _walletOrigin = "https://wallet.dcnetio.com";
27
27
 
28
28
  if(walletOpenOrgin) {
package/lib/dc.ts CHANGED
@@ -85,7 +85,7 @@ export class DC implements DCContext {
85
85
  this.dcChain = new ChainUtil();
86
86
  this.dcutil = new DcUtil(this.dcChain);
87
87
  // //todo 发布注释 remove
88
- // this.dcutil.defaultPeerId= "12D3KooWEGzh4AcbJrfZMfQb63wncBUpscMEEyiMemSWzEnjVCPf";
88
+ // this.dcutil.defaultPeerId= "12D3KooWEGzh4AcbJrfZMfQb63wncBUpscMEEyiMemSWzEnjVCPf";
89
89
  // //todo remove end
90
90
  this.appInfo = options.appInfo || ({} as APPInfo);
91
91
  this.accountInfo = {} as AccountInfo;
@@ -39,10 +39,8 @@ export const Errors = {
39
39
  export class AccountManager {
40
40
  dc: DcUtil;
41
41
  chainUtil: ChainUtil | undefined;
42
- connectedDc: DCConnectInfo = {};
43
42
  context: DCContext;
44
43
  constructor(context: DCContext) {
45
- this.connectedDc = context.connectedDc;
46
44
  this.dc = context.dcutil;
47
45
  this.chainUtil = context.dcChain;
48
46
  this.context = context;
@@ -50,7 +48,7 @@ export class AccountManager {
50
48
 
51
49
  // 获取用户备用节点
52
50
  getAccountNodeAddr = async (): Promise<[Multiaddr | null, Error | null]> => {
53
- if (!this.connectedDc.client) {
51
+ if (!this.context.connectedDc.client) {
54
52
  console.error("dcClient is null");
55
53
  return [null, Errors.ErrNoDcPeerConnected];
56
54
  }
@@ -78,7 +76,7 @@ export class AccountManager {
78
76
  getUserInfoWithNft = async (
79
77
  nftAccount: string
80
78
  ): Promise<[User | null, Error | null]> => {
81
- if (!this.connectedDc.client) {
79
+ if (!this.context.connectedDc.client) {
82
80
  console.error("dcClient is null");
83
81
  return [null, Errors.ErrNoDcPeerConnected];
84
82
  }
@@ -94,7 +92,7 @@ export class AccountManager {
94
92
  bindAccessPeerToUser = async (
95
93
  peerAddr: Multiaddr
96
94
  ): Promise<[boolean | null, Error | null]> => {
97
- if (!this.connectedDc.client) {
95
+ if (!this.context.connectedDc.client) {
98
96
  console.error("dcClient is null");
99
97
  return [false, Errors.ErrNoDcPeerConnected];
100
98
  }
@@ -113,7 +111,7 @@ export class AccountManager {
113
111
  }
114
112
  // 绑定节点
115
113
  const blockHeight = await this.chainUtil.getBlockHeight();
116
- const accountClient = new AccountClient(this.connectedDc.client);
114
+ const accountClient = new AccountClient(this.context.connectedDc.client);
117
115
  const bindResult = await accountClient.bindAccessPeerToUser(
118
116
  this.context,
119
117
  blockHeight ? blockHeight : 0,
@@ -137,15 +135,15 @@ export class AccountManager {
137
135
  mnemonic: string
138
136
  ): Promise<[NFTBindStatus, Error | null]> {
139
137
  // 检查节点连接
140
- if (!this.connectedDc.client) {
138
+ if (!this.context.connectedDc.client) {
141
139
  return [NFTBindStatus.DcPeerNotConnected, Errors.ErrNoDcPeerConnected];
142
140
  }
143
- if (!this.connectedDc.nodeAddr) {
141
+ if (!this.context.connectedDc.nodeAddr) {
144
142
  return [NFTBindStatus.DcPeerNotConnected, Errors.ErrNodeAddrIsNull];
145
143
  }
146
144
 
147
145
  try {
148
- const connectedPeerIdStr = this.connectedDc.nodeAddr.getPeerId();
146
+ const connectedPeerIdStr = this.context.connectedDc.nodeAddr.getPeerId();
149
147
  if (!connectedPeerIdStr) {
150
148
  return [NFTBindStatus.DcPeerNotConnected, Errors.ErrNodeAddrIsNull];
151
149
  }
@@ -167,7 +165,7 @@ export class AccountManager {
167
165
  }
168
166
 
169
167
  // 获取客户端
170
- const accountClient = new AccountClient(this.connectedDc.client);
168
+ const accountClient = new AccountClient(this.context.connectedDc.client);
171
169
  // 调用账户绑定API
172
170
  await accountClient.accountBind(req, mnemonic, this.context);
173
171
 
@@ -471,7 +469,7 @@ export class AccountManager {
471
469
  if (!appId) {
472
470
  return [null, new AccountError("App ID is required")];
473
471
  }
474
- if (!this.connectedDc.nodeAddr) {
472
+ if (!this.context.connectedDc.nodeAddr) {
475
473
  return [null, new AccountError("No connected node")];
476
474
  }
477
475
  let subPrivateKey: Ed25519PrivKey;
@@ -494,7 +492,7 @@ export class AccountManager {
494
492
  return [null, new AccountError("Failed to get blockchain height")];
495
493
  }
496
494
  // 获取服务器节点ID
497
- const serverPidStr = this.connectedDc.nodeAddr.getPeerId();
495
+ const serverPidStr = this.context.connectedDc.nodeAddr.getPeerId();
498
496
  if (!serverPidStr) {
499
497
  return [null, new AccountError("No connected peer ID")];
500
498
  }
@@ -529,11 +527,11 @@ export class AccountManager {
529
527
  }
530
528
 
531
529
  // 获取token
532
- if (!this.connectedDc.client) {
530
+ if (!this.context.connectedDc.client) {
533
531
  throw [null, Errors.ErrNoAccountPeerConnected];
534
532
  }
535
- if (this.connectedDc.client.token == "") {
536
- const token = await this.connectedDc.client.GetToken(
533
+ if (this.context.connectedDc.client.token == "") {
534
+ const token = await this.context.connectedDc.client.GetToken(
537
535
  this.context.appInfo.appId || "",
538
536
  privateKey.publicKey.string(),
539
537
  async (payload: Uint8Array): Promise<Uint8Array> => {
@@ -553,7 +551,7 @@ export class AccountManager {
553
551
  signature: signature,
554
552
  };
555
553
 
556
- const client = new AccountClient(this.connectedDc.client);
554
+ const client = new AccountClient(this.context.connectedDc.client);
557
555
  // 添加子公钥
558
556
  await client.addSubPubkey(req);
559
557
  // Wait for app account creation
@@ -629,10 +627,10 @@ export class AccountManager {
629
627
  if(!this.context.publicKey){
630
628
  throw Errors.ErrAccountPublicKeyIsNull;
631
629
  }
632
- if(!this.connectedDc.client){
630
+ if(!this.context.connectedDc.client){
633
631
  throw Errors.ErrNoDcPeerConnected;
634
632
  }
635
- if(!this.connectedDc.nodeAddr){
633
+ if(!this.context.connectedDc.nodeAddr){
636
634
  throw Errors.ErrNodeAddrIsNull;
637
635
  }
638
636
  const dbinfo = threadId + "|" + rk + "|" + sk + "|" + remark;
@@ -643,8 +641,8 @@ export class AccountManager {
643
641
  if (blockHeight === undefined) {
644
642
  throw new AccountError("Failed to get blockchain height");
645
643
  }
646
- if (this.connectedDc.client.token == "") {
647
- const token = await this.connectedDc.client.GetToken(
644
+ if (this.context.connectedDc.client.token == "") {
645
+ const token = await this.context.connectedDc.client.GetToken(
648
646
  this.context.appInfo.appId || "",
649
647
  this.context.publicKey.string(),
650
648
  async (payload: Uint8Array): Promise<Uint8Array> => {
@@ -655,8 +653,8 @@ export class AccountManager {
655
653
  throw new AccountError("Failed to get token");
656
654
  }
657
655
  }
658
- const accountClient = new AccountClient(this.connectedDc.client);
659
- const serverPidStr = this.connectedDc.nodeAddr.getPeerId() || "";
656
+ const accountClient = new AccountClient(this.context.connectedDc.client);
657
+ const serverPidStr = this.context.connectedDc.nodeAddr.getPeerId() || "";
660
658
  const serverPidBytes = new TextEncoder().encode(serverPidStr);
661
659
  // 生成签名数据
662
660
  const hvalue = uint32ToLittleEndianBytes(blockHeight);
@@ -267,7 +267,6 @@ export class AIProxyClient {
267
267
  const onEndCallback = async () => {
268
268
  clearTimeoutTimer();
269
269
  if (isAborted || checkAborted() || isCompleted) return;
270
- console.log('*********** onEndCallback ***********1111');
271
270
  isCompleted = true;
272
271
  if (onStreamResponse) {
273
272
  onStreamResponse(AIStreamResponseFlag.CONNECTION_CLOSED, "", "");
@@ -277,8 +276,6 @@ export class AIProxyClient {
277
276
  const onErrorCallback = async (error: unknown) => {
278
277
  if (isAborted || checkAborted() || isCompleted) return;
279
278
  //不要标记完成,和清理定时器,统一由onEndCallback处理
280
- // isCompleted = true; //
281
- // clearTimeoutTimer();
282
279
  if (onStreamResponse) {
283
280
  onStreamResponse(AIStreamResponseFlag.OTHER_ERROR, "", error instanceof Error ? error.message : String(error));
284
281
  }
@@ -79,7 +79,7 @@ export class KeyValueDB {
79
79
  vaccount?: string
80
80
  ): Promise<[string | null, Error | null]> {
81
81
  if (!writerPubkey) {//没有指定写入者,则获取该key的最新值
82
- const [values, err] = await this.getWithIndex("dc_timestamp_index", "",1, "", Direction.Reverse, 0,);
82
+ const [values, err] = await this.getWithIndex("indexkey_keyself_" + key, "", 1, "", Direction.Reverse, 0, vaccount);
83
83
  if (err) {
84
84
  return [null, err];
85
85
  }
@@ -9,7 +9,7 @@ import { createLogger } from "../util/logger";
9
9
  import { ThemeAuthInfo, ThemeComment } from "../common/types/types";
10
10
  import { Direction } from "../common/define";
11
11
  import { ThemePermission } from "../common/constants";
12
- import {padPositiveInt30} from "../util/utils";
12
+ import {padPositiveInt20} from "../util/utils";
13
13
  const logger = createLogger('KeyValueModule');
14
14
  const indexkey_dckv = "indexkey_dckv"; //索引键名,keyvalue设置过程中key本身的索引键
15
15
  /**
@@ -167,7 +167,7 @@ export class KeyValueModule implements DCModule, IKeyValueOperations {
167
167
  for (const index of indexArray) {
168
168
  let indexValue = "";
169
169
  if( index.type === "number" ){ //
170
- indexValue = padPositiveInt30(index.value);
170
+ indexValue = padPositiveInt20(index.value);
171
171
  }else{
172
172
  indexValue = index.value;
173
173
  }
@@ -179,10 +179,6 @@ export class KeyValueModule implements DCModule, IKeyValueOperations {
179
179
  } catch (error) {
180
180
  logger.error(`设置索引,解析失败:`, error);
181
181
  }
182
- //追加时间戳索引,保证每次写入的唯一性
183
- const timestamp = Date.now();
184
- const timestampStr = padPositiveInt30(timestamp);
185
- strIndexs += `dc_timestamp_index:${timestampStr}`;
186
182
  const res = await kvdb.set(key, value, strIndexs, vaccount);
187
183
  return res;
188
184
  } catch (error) {
@@ -322,7 +318,7 @@ export class KeyValueModule implements DCModule, IKeyValueOperations {
322
318
  const offset = options.offset? options.offset: 0;
323
319
  let indexValueStr = "";
324
320
  if( options.type === "number" ){ //
325
- indexValueStr = padPositiveInt30(indexValue);
321
+ indexValueStr = padPositiveInt20(indexValue);
326
322
  }
327
323
  try {
328
324
  const res = await kvdb.getWithIndex(indexKey, indexValueStr, limit,seekKey, direction,offset, vaccount);
@@ -331,6 +327,45 @@ export class KeyValueModule implements DCModule, IKeyValueOperations {
331
327
  return [null, error instanceof Error ? error : new Error(String(error))];
332
328
  }
333
329
  }
330
+
331
+ /**
332
+ * 按设置时间顺序获取主题的的键值对列表
333
+ * @param kvdb KeyValueDB实例
334
+ * @param limit 返回结果数量限制
335
+ * @param seekKey 查询起始键,用于分页查询
336
+ * @param direction 查询方向
337
+ * @param offset 结果偏移量
338
+ * @param vaccount 可选的虚拟账户
339
+ * @returns [值列表数组生成的json字符串, 错误信息] 数组的每个元素的格式: key:value$$$dckv_extra$$${'dc_timestamp':'%d','dc_opuser':'%s'}
340
+ */
341
+ async getWithTimeOrder(
342
+ kvdb: KeyValueDB,
343
+ timestamp: number,//毫秒时间戳
344
+ options: { limit?: number; seekKey?: string; direction?: Direction; offset?: number },
345
+ vaccount?: string
346
+ ): Promise<[string | null, Error | null]> {
347
+ const err = this.assertInitialized();
348
+ if (err) {
349
+ return [null, err];
350
+ }
351
+ let timestampStr = "";
352
+ if( timestamp > 0 ){
353
+ //把毫秒时间转为微妙时间戳字符串,与DC节点存储的时间戳格式一致
354
+ timestampStr = padPositiveInt20(timestamp * 1000);
355
+ //前面补0,保证长度为20位
356
+ timestampStr = timestampStr.padStart(20, "0");
357
+ }
358
+ const limit = options.limit ? options.limit : 10;
359
+ const seekKey = options.seekKey ? options.seekKey : "";
360
+ const direction = options.direction ? options.direction : Direction.Forward;
361
+ const offset = options.offset ? options.offset : 0;
362
+ try {
363
+ const res = await kvdb.getWithIndex("indexkey_timestamp", timestampStr, limit, seekKey, direction, offset, vaccount);
364
+ return res;
365
+ } catch (error) {
366
+ return [null, error instanceof Error ? error : new Error(String(error))];
367
+ }
368
+ }
334
369
 
335
370
 
336
371
  /**
package/lib/util/utils.ts CHANGED
@@ -236,16 +236,16 @@ function jsonStringify(value: any): string {
236
236
 
237
237
  /**
238
238
  * 将非负数字字符串(可带小数)格式化:
239
- * - 仅对整数部分左侧补零至 30
239
+ * - 仅对整数部分左侧补零至 20
240
240
  * - 小数部分(若有)原样保留
241
241
  * - 不进行数值运算,避免精度问题
242
242
  * 例:
243
- * - "123" -> "000000000000000000000000000123"
244
- * - "123.45" -> "000000000000000000000000000123.45"
245
- * - "0.5" -> "000000000000000000000000000000.5"
243
+ * - "123" -> "00000000000000000123"
244
+ * - "123.45" -> "00000000000000000123.45"
245
+ * - "0.5" -> "00000000000000000000.5"
246
246
  */
247
247
 
248
- function padPositiveInt30(v: string | number): string {
248
+ function padPositiveInt20(v: string | number): string {
249
249
  const s0 = String(v).trim();
250
250
  // 仅允许非负数字,支持一处小数点(不允许科学计数法/负号)
251
251
  if (!/^\d+(\.\d+)?$/.test(s0)) throw new Error("只接受非负数字(可带小数)");
@@ -258,9 +258,9 @@ function padPositiveInt30(v: string | number): string {
258
258
  // 去掉整数部分前导 0
259
259
  intPart = intPart.replace(/^0+/, "") || "0";
260
260
 
261
- if (intPart.length > 30) throw new Error("整数部分超过 30 位宽度");
261
+ if (intPart.length > 30) throw new Error("整数部分超过 20 位宽度");
262
262
 
263
- const paddedInt = intPart.padStart(30, "0");
263
+ const paddedInt = intPart.padStart(20, "0");
264
264
  return fracPart ? `${paddedInt}.${fracPart}` : paddedInt;
265
265
  }
266
266
 
@@ -285,5 +285,5 @@ export {
285
285
  parseUint32,
286
286
  hexToAscii,
287
287
  jsonStringify,
288
- padPositiveInt30
288
+ padPositiveInt20
289
289
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-dc-api",
3
- "version": "0.0.83",
3
+ "version": "0.0.85",
4
4
  "description": "web相关的dcapi",
5
5
  "type": "module",
6
6
  "browser": "dist/dc.min.js",
@@ -59,7 +59,7 @@
59
59
  "datastore-idb": "^3.0.1",
60
60
  "datastore-level": "^11.0.1",
61
61
  "google-protobuf": "~3.21.2",
62
- "grpc-libp2p-client": "^0.0.18",
62
+ "grpc-libp2p-client": "^0.0.19",
63
63
  "helia": "5.3.0",
64
64
  "interface-ipld-format": "^1.0.1",
65
65
  "it-to-buffer": "^4.0.7",