wowok 1.7.16 → 1.7.18

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/passport.js CHANGED
@@ -1,10 +1,13 @@
1
1
  var _a;
2
2
  import { Inputs } from '@mysten/sui/transactions';
3
- import { Protocol, ContextType, OperatorType, ValueType, SER_VALUE } from './protocol.js';
3
+ import { Protocol, ContextType, OperatorType, ValueType, SER_VALUE, IsContextWitness, MODULES, WitnessObjectModule, WitnessForModule } from './protocol.js';
4
4
  import { parse_object_type, array_unique, Bcs, ulebDecode, IsValidAddress, IsValidArray, readOption, readOptionString, deepCopy } from './utils.js';
5
5
  import { ERROR, Errors } from './exception.js';
6
- import { CMD_CHECK_GUARD, Guard, GuardMaker } from './guard.js';
6
+ import { CMD_CHECK_GUARD, Guard, GUARD_QUERIES, GuardMaker } from './guard.js';
7
7
  import { bcs } from '@mysten/sui/bcs';
8
+ import { Service } from './service.js';
9
+ import { Arbitration } from './arbitration.js';
10
+ import { Progress } from './progress.js';
8
11
  export class GuardParser {
9
12
  constructor(guards) {
10
13
  this.guard_list = [];
@@ -15,63 +18,176 @@ export class GuardParser {
15
18
  // cmd already in query_list, so filter it out.
16
19
  //console.log(g.constant); console.log(g.input)
17
20
  g.constant.filter((i) => i.bWitness).forEach((v) => {
18
- const cmd = g.input.filter((k) => k.identifier === v.identifier && k.cmd !== undefined).map((k) => k.cmd);
19
21
  let cited = 0;
20
22
  g.input.forEach((k) => {
21
23
  if (k.identifier === v.identifier)
22
24
  cited++;
23
25
  });
24
- ret.push({ guard: g.id, witness: undefined, identifier: v.identifier, type: v.type, cmd: cmd ?? [], cited: cited });
26
+ ret.push({ guard: g.id, witness: undefined, identifier: v.identifier, ..._a.ConstantWitnessModule(v),
27
+ type: v.type, cmd: v.cmd, witnessTypes: v.witness, cited: cited }); // module 很重要,需要得到
25
28
  });
26
29
  });
27
30
  return ret;
28
31
  };
32
+ this.fetch_witness = async (fill) => {
33
+ if (!fill || fill.length === 0)
34
+ return;
35
+ // 所有需要查询的witness, 根据module字段获得
36
+ const witness = array_unique(fill.filter(v => v.witness_module !== undefined).map(v => v.witness));
37
+ if (witness.length === 0)
38
+ return;
39
+ const res = await Protocol.Instance().query_raw(witness, { showType: true, showContent: true });
40
+ //console.log(res);
41
+ const witnessObjectInfo = new Map(); // 报错witness 类型信息等
42
+ // 查询并填充cmd的witness
43
+ for (let i = 0; i < res.length; ++i) {
44
+ const v = res[i];
45
+ const type_raw = v?.data?.type ?? undefined;
46
+ const objectid = v?.data?.objectId ?? undefined;
47
+ if (!type_raw || !objectid)
48
+ return;
49
+ const t = Protocol.Instance().object_name_from_type_repr(type_raw);
50
+ switch (t) {
51
+ case 'Progress': {
52
+ const machine = v?.data?.content?.fields?.machine;
53
+ fill.filter(v => v.witness === objectid && v.witness_module === MODULES.progress).forEach(v => {
54
+ v.cmd.forEach(i => {
55
+ switch (i.witness) {
56
+ case ContextType.TYPE_PROGRESS_MACHINE:
57
+ i.witness_object = machine;
58
+ break;
59
+ }
60
+ });
61
+ });
62
+ witnessObjectInfo.set(objectid, { module: MODULES.progress });
63
+ break;
64
+ }
65
+ case 'Order': {
66
+ const service = v?.data?.content?.fields?.service;
67
+ const machine = v?.data?.content?.fields?.machine;
68
+ const progress = v?.data?.content?.fields?.progress;
69
+ fill.filter(v => v.witness === objectid && v.witness_module === MODULES.order).forEach(v => {
70
+ v.cmd.forEach(i => {
71
+ switch (i.witness) {
72
+ case ContextType.TYPE_ORDER_MACHINE:
73
+ i.witness_object = machine;
74
+ break;
75
+ case ContextType.TYPE_ORDER_PROGRESS:
76
+ i.witness_object = progress;
77
+ break;
78
+ case ContextType.TYPE_ORDER_SERVICE:
79
+ i.witness_object = service;
80
+ break;
81
+ }
82
+ });
83
+ });
84
+ witnessObjectInfo.set(objectid, { module: MODULES.order, type: Service.parseOrderObjectType(type_raw) });
85
+ break;
86
+ }
87
+ case 'Arb': {
88
+ const arbitration = v?.data?.content?.fields?.arbitration;
89
+ const order = v?.data?.content?.fields?.order;
90
+ const order_res = await Protocol.Instance().query_raw([order], { showType: true, showContent: true });
91
+ const service = order_res[0]?.data?.content?.fields?.service;
92
+ const machine = order_res[0]?.data?.content?.fields?.machine;
93
+ const progress = order_res[0]?.data?.content?.fields?.progress;
94
+ const order_type = order_res[0]?.data?.type ?? undefined;
95
+ fill.filter(v => v.witness === objectid && v.witness_module === MODULES.arb).forEach(v => {
96
+ v.cmd.forEach(i => {
97
+ switch (i.witness) {
98
+ case ContextType.TYPE_ARB_MACHINE:
99
+ i.witness_object = machine;
100
+ break;
101
+ case ContextType.TYPE_ARB_PROGRESS:
102
+ i.witness_object = progress;
103
+ break;
104
+ case ContextType.TYPE_ARB_SERVICE:
105
+ i.witness_object = service;
106
+ break;
107
+ case ContextType.TYPE_ARB_ORDER:
108
+ i.witness_object = order;
109
+ break;
110
+ case ContextType.TYPE_ARB_ARBITRATION:
111
+ i.witness_object = arbitration;
112
+ break;
113
+ }
114
+ });
115
+ });
116
+ witnessObjectInfo.set(objectid, { module: MODULES.arb, type: Arbitration.parseArbObjectType(type_raw),
117
+ order: order, order_type: order_type
118
+ });
119
+ break;
120
+ }
121
+ }
122
+ }
123
+ ;
124
+ // 检查结果的完整性
125
+ fill.filter(v => v.witness_module !== undefined).forEach(v => {
126
+ v.cmd.forEach(i => {
127
+ if (i.witness && !i.witness_object) {
128
+ ERROR(Errors.Fail, `fetch_witness : ${i}`);
129
+ }
130
+ });
131
+ });
132
+ return witnessObjectInfo;
133
+ };
29
134
  this.done = async (fill, onPassportQueryReady) => {
30
135
  let objects = [];
136
+ // 填充所有的witness object
137
+ const witnessObjectInfo = await this.fetch_witness(fill);
31
138
  // check all witness and get all objects to query.
32
139
  this.guard_list.forEach((g) => {
33
140
  g.constant.forEach((v) => {
34
141
  if (v.bWitness) {
35
- const value = fill?.find((i) => i.identifier === v.identifier);
142
+ const value = fill?.find((i) => i.identifier === v.identifier && i.guard === g.id);
36
143
  if (!value) {
37
144
  ERROR(Errors.Fail, 'done: invalid witness ' + v.identifier);
38
145
  }
39
146
  else {
40
- v.value = value.witness;
147
+ v.value = value.witness; // 写witness
41
148
  }
42
149
  }
43
150
  });
44
151
  g.input.filter((v) => v.cmd !== undefined).forEach((i) => {
45
152
  if (i.identifier !== undefined) {
46
- const value = g.constant.find((c) => c.identifier === i.identifier && c.type === ValueType.TYPE_ADDRESS);
47
- if (!value || !IsValidAddress(value.value))
48
- ERROR(Errors.Fail, 'done: invalid identifier ' + i.identifier);
49
- objects.push(value.value);
153
+ if (IsContextWitness(i.value)) { //是否是 type witness
154
+ const value = fill?.find(c => c.guard === g.id && c.identifier === i.identifier);
155
+ const cmd = value?.cmd.find(c => c.cmd === i.cmd);
156
+ if (!value || !cmd || !IsValidAddress(cmd.witness_object))
157
+ ERROR(Errors.Fail, `witness invalid or not found: ${i}`);
158
+ objects.push(cmd.witness_object); // 将witness查询对象地址加入
159
+ }
160
+ else { // self witness
161
+ const value = g.constant.find((c) => c.identifier === i.identifier && c.type === ValueType.TYPE_ADDRESS);
162
+ if (!value || !IsValidAddress(value.value))
163
+ ERROR(Errors.Fail, 'done: invalid identifier ' + i.identifier);
164
+ objects.push(value.value); // const address(witness or not)
165
+ }
50
166
  }
51
167
  else {
52
- objects.push(i.value);
168
+ objects.push(i.value); //@ address
53
169
  }
54
170
  });
55
171
  });
56
172
  if (onPassportQueryReady) {
57
173
  if (objects.length === 0) {
58
- onPassportQueryReady(this.done_helper([]));
174
+ onPassportQueryReady(this.done_helper([], fill, witnessObjectInfo));
59
175
  return;
60
176
  }
61
177
  Protocol.Instance().query_raw(array_unique(objects), { showType: true }).then((res) => {
62
- onPassportQueryReady(this.done_helper(res));
178
+ onPassportQueryReady(this.done_helper(res, fill, witnessObjectInfo));
63
179
  }).catch(e => {
64
180
  console.log(e);
65
181
  onPassportQueryReady(undefined);
66
182
  });
67
- return undefined;
183
+ return;
68
184
  }
69
185
  else {
70
186
  let res = [];
71
187
  if (objects.length > 0) {
72
188
  res = await Protocol.Instance().query_raw(array_unique(objects), { showType: true });
73
189
  }
74
- return this.done_helper(res);
190
+ return this.done_helper(res, fill, witnessObjectInfo);
75
191
  }
76
192
  };
77
193
  // create onchain query for objects : object, movecall-types, id
@@ -91,6 +207,7 @@ export class GuardParser {
91
207
  };
92
208
  this.guards = guards;
93
209
  }
210
+ // ============================================
94
211
  static Parse_Guard_Helper(guards, res) {
95
212
  const protocol = Protocol.Instance();
96
213
  const me = new _a(guards);
@@ -112,17 +229,122 @@ export class GuardParser {
112
229
  });
113
230
  return me;
114
231
  }
115
- done_helper(res) {
232
+ // 检查cmd(含非witness)和witness的模块一致性,并返回模块
233
+ static ConstantWitnessModule(constant) {
234
+ let module;
235
+ let witness_module;
236
+ for (let i = 0; i < constant.cmd.length; ++i) {
237
+ if (constant.cmd[i].witness !== undefined) { // witness cmd
238
+ if (!IsContextWitness(constant.cmd[i].witness)) {
239
+ ERROR(Errors.Fail, `ConstantWitnessModule witness type invalid on identifier ${constant}`);
240
+ }
241
+ const m = WitnessObjectModule(constant.cmd[i].witness);
242
+ if (!witness_module) {
243
+ witness_module = m;
244
+ }
245
+ else {
246
+ if (witness_module !== m) {
247
+ ERROR(Errors.Fail, `ConstantWitnessModule wintesses modules are different on identifier ${constant}`);
248
+ }
249
+ }
250
+ }
251
+ else {
252
+ const q = GUARD_QUERIES.find((q) => q.query_id == constant.cmd[i].cmd);
253
+ if (q) {
254
+ if (!module) {
255
+ module = q.module;
256
+ }
257
+ else {
258
+ if (module !== q.module) {
259
+ ERROR(Errors.Fail, `ConstantWitnessModule modules are different on identifier ${constant}`);
260
+ }
261
+ }
262
+ }
263
+ else {
264
+ ERROR(Errors.Fail, `ConstantWitnessModule. cmd not found on identifier ${constant}`);
265
+ }
266
+ }
267
+ }
268
+ for (let i = 0; i < constant.witness.length; ++i) {
269
+ const m = WitnessObjectModule(constant.witness[i]);
270
+ if (!witness_module) {
271
+ witness_module = m;
272
+ }
273
+ else {
274
+ if (witness_module !== m) {
275
+ ERROR(Errors.Fail, `ConstantWitnessModule modules are different on identifier ${constant}`);
276
+ }
277
+ }
278
+ }
279
+ return { module: module, witness_module: witness_module };
280
+ }
281
+ static AddConstantWitness(constants, identifier, type) {
282
+ const c = constants.find(i => i.bWitness && i.identifier === identifier);
283
+ if (!c)
284
+ ERROR(Errors.Fail, `AddConstantWitness identifer ${identifier} with witness not found`);
285
+ const module = _a.ConstantWitnessModule(c);
286
+ const m = WitnessObjectModule(type);
287
+ if (module.witness_module && m !== module.witness_module) {
288
+ ERROR(Errors.Fail, `AddConstantWitness.type module not matach ${type}`);
289
+ }
290
+ const n = c.witness.find(v => v === type);
291
+ c.info = { module: m };
292
+ if (!n)
293
+ c.witness.push(type);
294
+ }
295
+ static AddConstantCmd(constants, identifier, cmd) {
296
+ let c;
297
+ if (cmd.witness !== undefined) {
298
+ c = constants.find(i => i.bWitness && i.identifier === identifier);
299
+ if (!c)
300
+ ERROR(Errors.Fail, `AddConstantCmd identifer ${identifier} with witness not found`);
301
+ const module = _a.ConstantWitnessModule(c);
302
+ GuardMaker.checkCmdWitness(cmd.cmd, cmd.witness);
303
+ const m = WitnessForModule(cmd.witness);
304
+ if (module.witness_module && m !== module.witness_module) { // 使用module_witness字段
305
+ ERROR(Errors.WitnessTypeInvalid, `AddConstantCmd module not match ${identifier}`);
306
+ }
307
+ c.info = { module: m };
308
+ }
309
+ else {
310
+ c = constants.find(i => i.identifier === identifier);
311
+ if (!c)
312
+ ERROR(Errors.Fail, `AddConstantCmd identifer ${identifier} with witness not found`);
313
+ const module = _a.ConstantWitnessModule(c);
314
+ const m = GUARD_QUERIES.find(v => v.query_id === cmd.cmd);
315
+ if (!m) {
316
+ ERROR(Errors.Fail, `AddConstantCmd.cmd not found ${cmd}`);
317
+ }
318
+ if (module.module && m?.module !== module.module) { // 使用module字段
319
+ ERROR(Errors.Fail, `AddConstantCmd module not match ${identifier}`);
320
+ }
321
+ }
322
+ c.cmd.push(cmd); //@ 每个命令都添加进去,不考虑重复
323
+ }
324
+ done_helper(res, fill, info) {
116
325
  let query = [];
117
326
  let guards = [];
118
327
  this.guard_list.forEach(g => {
119
328
  guards.push(g.id);
329
+ let object_id;
120
330
  g.input.filter((v) => v.cmd !== undefined).forEach(q => {
121
- let id = q.value;
122
- if (!id && q.identifier !== undefined) {
123
- id = g.constant.find((i) => i.identifier == q.identifier)?.value;
331
+ if (q.identifier !== undefined) {
332
+ if (IsContextWitness(q.value)) { //是否是 type witness
333
+ const value = fill?.find(c => c.guard === g.id && c.identifier === q.identifier);
334
+ object_id = value?.cmd.find(c => c.cmd === q.cmd)?.witness_object;
335
+ }
336
+ else { // self witness
337
+ const value = g.constant.find((c) => c.identifier === q.identifier && c.type === ValueType.TYPE_ADDRESS);
338
+ if (!value || !IsValidAddress(value.value)) {
339
+ ERROR(Errors.Fail, `done_helper: invalid identifier ${q.identifier}`);
340
+ }
341
+ object_id = value?.value;
342
+ }
343
+ }
344
+ else {
345
+ object_id = q.value; //@ address
124
346
  }
125
- let r = res.find(r => r.data?.objectId == id);
347
+ let r = res.find(r => r.data?.objectId == object_id);
126
348
  if (!r) {
127
349
  ERROR(Errors.Fail, 'query object not match');
128
350
  }
@@ -133,10 +355,11 @@ export class GuardParser {
133
355
  query.push(object);
134
356
  });
135
357
  });
136
- return { query: query, info: this.guard_list };
358
+ return { query: query, info: this.guard_list, witnessObjectInfo: info };
137
359
  }
138
360
  }
139
361
  _a = GuardParser;
362
+ // 解析一个Guard的数据,生成树结构和表结构
140
363
  GuardParser.DeGuardObject_FromData = (guard_constants, guard_input_bytes) => {
141
364
  let constants = _a.parse_constant(guard_constants);
142
365
  // console.log(constants)
@@ -152,7 +375,7 @@ GuardParser.DeGuardObject_FromData = (guard_constants, guard_input_bytes) => {
152
375
  }
153
376
  return { object: stack.pop(), constant: constants };
154
377
  };
155
- /// convert guard-on-chain to js object
378
+ /// 解析一个Guard地址,生成树结构(通过ResolveData)和表结构。 用于UI对单个guard作图
156
379
  GuardParser.DeGuardObject = async (protocol, guard) => {
157
380
  if (!IsValidAddress(guard)) {
158
381
  ERROR(Errors.IsValidAddress, 'GuardObject guard');
@@ -192,6 +415,28 @@ GuardParser.ResolveData = (constants, stack, current) => {
192
415
  current.child.push(param);
193
416
  stack.push(current);
194
417
  return;
418
+ case OperatorType.TYPE_SAFE_U8:
419
+ current.ret_type = ValueType.TYPE_U8;
420
+ if (stack.length < 1)
421
+ ERROR(Errors.Fail, 'ResolveData: TYPE_SAFE_U8');
422
+ var param = stack.pop();
423
+ if (!param.ret_type || !GuardMaker.match_u256(param.ret_type)) {
424
+ ERROR(Errors.Fail, 'ResolveData: TYPE_SAFE_U8 type invalid');
425
+ }
426
+ current.child.push(param);
427
+ stack.push(current);
428
+ return;
429
+ case OperatorType.TYPE_SAFE_U64:
430
+ current.ret_type = ValueType.TYPE_U64;
431
+ if (stack.length < 1)
432
+ ERROR(Errors.Fail, 'ResolveData: TYPE_SAFE_U64');
433
+ var param = stack.pop();
434
+ if (!param.ret_type || !GuardMaker.match_u256(param.ret_type)) {
435
+ ERROR(Errors.Fail, 'ResolveData: TYPE_SAFE_U64 type invalid');
436
+ }
437
+ current.child.push(param);
438
+ stack.push(current);
439
+ return;
195
440
  case OperatorType.TYPE_STRING_LOWERCASE:
196
441
  current.ret_type = ValueType.TYPE_STRING;
197
442
  if (stack.length < 1)
@@ -272,17 +517,17 @@ GuardParser.ResolveData = (constants, stack, current) => {
272
517
  return;
273
518
  case OperatorType.TYPE_QUERY:
274
519
  if (!current?.cmd)
275
- ERROR(Errors.Fail, 'OperateParamCount: cmd invalid ' + current.type);
520
+ ERROR(Errors.Fail, 'ResolveData: cmd invalid ' + current.type);
276
521
  let r = Guard.GetCmd(current.cmd);
277
522
  if (!r)
278
- ERROR(Errors.Fail, 'OperateParamCount: cmd not supported ' + current.type);
523
+ ERROR(Errors.Fail, 'ResolveData: cmd not supported ' + current.type);
279
524
  current.ret_type = r?.return;
280
525
  if (stack.length < r.parameters.length)
281
- ERROR(Errors.Fail, 'OperateParamCount: cmd param lost ' + current.type);
526
+ ERROR(Errors.Fail, 'ResolveData: cmd param lost ' + current.type);
282
527
  r.parameters.forEach((e) => {
283
528
  let d = stack.pop();
284
529
  if (!d?.ret_type || d.ret_type != e) {
285
- ERROR(Errors.Fail, 'OperateParamCount: cmd param not match ' + current.type);
530
+ ERROR(Errors.Fail, 'ResolveData: cmd param not match ' + current.type);
286
531
  }
287
532
  current.child.push(d);
288
533
  });
@@ -326,13 +571,27 @@ GuardParser.ResolveData = (constants, stack, current) => {
326
571
  case ContextType.TYPE_CONSTANT:
327
572
  let v = constants.find((e) => e.identifier == current?.identifier);
328
573
  if (!v)
329
- ERROR(Errors.Fail, 'OperateParamCount: identifier invalid ' + current.type);
574
+ ERROR(Errors.Fail, 'ResolveData: identifier invalid ' + current.type);
330
575
  current.ret_type = v?.type;
331
576
  stack.push(current);
332
577
  return;
578
+ case ContextType.TYPE_ARB_ARBITRATION:
579
+ case ContextType.TYPE_ARB_MACHINE:
580
+ case ContextType.TYPE_ARB_ORDER:
581
+ case ContextType.TYPE_ARB_PROGRESS:
582
+ case ContextType.TYPE_ARB_SERVICE:
583
+ case ContextType.TYPE_ORDER_MACHINE:
584
+ case ContextType.TYPE_ORDER_PROGRESS:
585
+ case ContextType.TYPE_ORDER_SERVICE:
586
+ case ContextType.TYPE_PROGRESS_MACHINE: {
587
+ current.ret_type = ValueType.TYPE_ADDRESS;
588
+ stack.push(current);
589
+ return;
590
+ }
333
591
  }
334
- ERROR(Errors.Fail, 'OperateParamCount: type invalid ' + current.type);
592
+ ERROR(Errors.Fail, 'ResolveData: type invalid ' + current.type);
335
593
  };
594
+ // 解析一些Guards,生成parser结构。用于生成fill数据或进行passport验证。
336
595
  GuardParser.Create = async (guards) => {
337
596
  if (!IsValidArray(guards, IsValidAddress)) {
338
597
  ERROR(Errors.InvalidParam, 'GuardParser.Create: guards invalid');
@@ -399,7 +658,7 @@ GuardParser.parse_constant = (constants) => {
399
658
  const data = Uint8Array.from(v.value);
400
659
  const type = data.slice(0, 1)[0];
401
660
  if (v.bWitness) { //@ witness
402
- ret.push({ identifier: v.identifier, type: type, bWitness: v.bWitness, value: undefined });
661
+ ret.push({ identifier: v.identifier, type: type, bWitness: v.bWitness, value: undefined, cmd: [], witness: [] });
403
662
  return;
404
663
  }
405
664
  var value = data.slice(1);
@@ -437,7 +696,7 @@ GuardParser.parse_constant = (constants) => {
437
696
  default:
438
697
  ERROR(Errors.Fail, 'GuardObject constant type invalid:' + type);
439
698
  }
440
- ret.push({ identifier: v.identifier, type: type, bWitness: v.bWitness, value: value });
699
+ ret.push({ identifier: v.identifier, type: type, bWitness: v.bWitness, value: value, witness: [], cmd: [] });
441
700
  });
442
701
  return ret;
443
702
  };
@@ -457,6 +716,8 @@ GuardParser.parse_bcs = (constants, chain_bytes) => {
457
716
  case OperatorType.TYPE_LOGIC_NOT:
458
717
  case OperatorType.TYPE_NUMBER_ADDRESS:
459
718
  case OperatorType.TYPE_STRING_LOWERCASE:
719
+ case OperatorType.TYPE_SAFE_U64:
720
+ case OperatorType.TYPE_SAFE_U8:
460
721
  break;
461
722
  case OperatorType.TYPE_LOGIC_AS_U256_GREATER:
462
723
  case OperatorType.TYPE_LOGIC_AS_U256_GREATER_EQUAL:
@@ -474,6 +735,25 @@ GuardParser.parse_bcs = (constants, chain_bytes) => {
474
735
  case OperatorType.TYPE_LOGIC_OR:
475
736
  value = arr.shift();
476
737
  break;
738
+ case ContextType.TYPE_ARB_ARBITRATION:
739
+ case ContextType.TYPE_ARB_MACHINE:
740
+ case ContextType.TYPE_ARB_ORDER:
741
+ case ContextType.TYPE_ARB_PROGRESS:
742
+ case ContextType.TYPE_ARB_SERVICE:
743
+ case ContextType.TYPE_ORDER_MACHINE:
744
+ case ContextType.TYPE_ORDER_PROGRESS:
745
+ case ContextType.TYPE_ORDER_SERVICE:
746
+ case ContextType.TYPE_PROGRESS_MACHINE:
747
+ identifier = arr.shift(); // identifier
748
+ let v = constants.find((v) => (v.identifier == identifier) &&
749
+ ((v.type == ValueType.TYPE_ADDRESS)));
750
+ if (!v) {
751
+ ERROR(Errors.Fail, `GuardParser.parse_bcs: indentifier ${identifier} with type ${ValueType.TYPE_ADDRESS} not in constant`);
752
+ }
753
+ value = type; //@ type used
754
+ //@ 将witness数据加入到常量中
755
+ _a.AddConstantWitness(constants, identifier, type);
756
+ break;
477
757
  case ContextType.TYPE_CONSTANT:
478
758
  identifier = arr.shift(); // identifier
479
759
  break;
@@ -539,24 +819,50 @@ GuardParser.parse_bcs = (constants, chain_bytes) => {
539
819
  break;
540
820
  case OperatorType.TYPE_QUERY:
541
821
  let t = arr.splice(0, 1); // data-type
542
- if (t[0] == ValueType.TYPE_ADDRESS) {
543
- let addr = Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
544
- arr.splice(0, 32); // address
545
- value = addr;
546
- cmd = bcs.u16().parse(Uint8Array.from(arr.splice(0, 2))); // cmd(u16)
547
- }
548
- else if (t[0] == ContextType.TYPE_CONSTANT) {
549
- let id = arr.splice(0, 1); // key
550
- let v = constants.find((v) => (v.identifier == id[0]) &&
551
- ((v.type == ValueType.TYPE_ADDRESS)));
552
- if (!v) {
553
- ERROR(Errors.Fail, 'GuardObject: indentifier not in constant');
822
+ switch (t[0]) {
823
+ case ValueType.TYPE_ADDRESS: {
824
+ let addr = Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
825
+ arr.splice(0, 32); // address
826
+ value = addr;
827
+ cmd = bcs.u16().parse(Uint8Array.from(arr.splice(0, 2))); // cmd(u16)
828
+ break;
554
829
  }
555
- identifier = id[0];
556
- cmd = bcs.u16().parse(Uint8Array.from(arr.splice(0, 2))); // cmd(u16)
557
- }
558
- else {
559
- ERROR(Errors.Fail, 'GuardObject: constant type invalid');
830
+ case ContextType.TYPE_CONSTANT: {
831
+ let id = arr.splice(0, 1); // key
832
+ let v = constants.find((v) => (v.identifier == id[0]) &&
833
+ ((v.type == ValueType.TYPE_ADDRESS)));
834
+ if (!v) {
835
+ ERROR(Errors.Fail, `GuardParser.parse_bcs: indentifier ${id[0]} with type ${ValueType.TYPE_ADDRESS} not in constant`);
836
+ }
837
+ identifier = id[0];
838
+ cmd = bcs.u16().parse(Uint8Array.from(arr.splice(0, 2))); // cmd(u16)
839
+ _a.AddConstantCmd(constants, identifier, { cmd: cmd }); //@ witness的cmd都添加(Self类型)
840
+ break;
841
+ }
842
+ case ContextType.TYPE_ARB_ARBITRATION:
843
+ case ContextType.TYPE_ARB_MACHINE:
844
+ case ContextType.TYPE_ARB_ORDER:
845
+ case ContextType.TYPE_ARB_PROGRESS:
846
+ case ContextType.TYPE_ARB_SERVICE:
847
+ case ContextType.TYPE_ORDER_MACHINE:
848
+ case ContextType.TYPE_ORDER_PROGRESS:
849
+ case ContextType.TYPE_ORDER_SERVICE:
850
+ case ContextType.TYPE_PROGRESS_MACHINE: {
851
+ let id = arr.splice(0, 1); // key
852
+ let v = constants.find((v) => (v.identifier == id[0]) && v.bWitness &&
853
+ ((v.type == ValueType.TYPE_ADDRESS))); // witness, address type
854
+ if (!v) {
855
+ ERROR(Errors.Fail, `GuardParser.parse_bcs: indentifier ${id[0]} with type ${ValueType.TYPE_ADDRESS} not in constant`);
856
+ }
857
+ identifier = id[0];
858
+ cmd = bcs.u16().parse(Uint8Array.from(arr.splice(0, 2))); // cmd(u16)
859
+ value = t[0]; //@ value used
860
+ // 添加witness cmd(witness类型)
861
+ _a.AddConstantCmd(constants, identifier, { witness: t[0], cmd: cmd });
862
+ break;
863
+ }
864
+ default:
865
+ ERROR(Errors.Fail, 'GuardObject: type invalid');
560
866
  }
561
867
  break;
562
868
  case ValueType.TYPE_OPTION_ADDRESS:
@@ -620,8 +926,8 @@ export class Passport {
620
926
  const res = await Protocol.Client().devInspectTransactionBlock({ sender: sender, transactionBlock: this.txb });
621
927
  return Passport.ResolveQueryRes(this.txb, res);
622
928
  };
623
- if (query.info.length === 0 || query.info.length > Passport.MAX_GUARD_COUNT) {
624
- ERROR(Errors.InvalidParam, 'guards');
929
+ if (query.info.length > Passport.MAX_GUARD_COUNT) {
930
+ ERROR(Errors.InvalidParam, `Passport: guards count max ${Passport.MAX_GUARD_COUNT}`);
625
931
  }
626
932
  this.txb = txb; //console.log(query)
627
933
  this.passport = this.txb.moveCall({
@@ -629,7 +935,7 @@ export class Passport {
629
935
  arguments: []
630
936
  });
631
937
  // add others guards, if any
632
- query.info.forEach((g) => {
938
+ query.info.forEach((g, guard_index) => {
633
939
  const ids = g.constant.filter((i) => i.bWitness).map((v) => v.identifier);
634
940
  const values = g.constant.filter((i) => i.bWitness).map((v) => {
635
941
  const bcs = Bcs.getInstance().ser(v.type, v.value);
@@ -647,6 +953,51 @@ export class Passport {
647
953
  arguments: [this.passport, guard, this.txb.pure.vector('u8', [].slice.call(ids)),
648
954
  this.txb.pure(bcs.vector(bcs.vector(bcs.u8())).serialize([...values]).toBytes())]
649
955
  });
956
+ // 对每个witness object处理所有的witness类型请求
957
+ const witness_objects = new Map();
958
+ g.constant.forEach(v => {
959
+ const types = [];
960
+ v.cmd.forEach(i => {
961
+ if (i.witness && IsContextWitness(i.witness) && !types.includes(i.witness)) {
962
+ types.push(i.witness);
963
+ }
964
+ });
965
+ v.witness.forEach(i => {
966
+ if (i && IsContextWitness(i) && !types.includes(i)) {
967
+ types.push(i);
968
+ }
969
+ });
970
+ if (types.length > 0) {
971
+ let obj = witness_objects.get(v.value); // 用户提供的witness地址
972
+ if (obj) {
973
+ obj.types = array_unique(types.concat(obj.types));
974
+ obj.identifier.push(v.identifier); // identifier加入
975
+ }
976
+ else {
977
+ witness_objects.set(v.value, { types: types, identifier: [v.identifier] });
978
+ }
979
+ }
980
+ });
981
+ // 调用witness object的witness
982
+ witness_objects.forEach((v, k) => {
983
+ const r = query.witnessObjectInfo?.get(k);
984
+ if (!r) {
985
+ ERROR(Errors.Fail, `Passport: witness not found ${k}`);
986
+ }
987
+ switch (r?.module) {
988
+ case MODULES.progress:
989
+ Progress.witness(txb, k, guard_index, v.identifier, this.passport);
990
+ break;
991
+ case MODULES.order:
992
+ Service.witness(txb, k, r.type, guard_index, v.identifier, v.types, this.passport);
993
+ break;
994
+ case MODULES.arb:
995
+ Arbitration.witness(txb, k, r.type, guard_index, v.identifier, v.types, r.order, r.order_type, this.passport);
996
+ break;
997
+ default:
998
+ ERROR(Errors.Fail, `Passport: witness type invalid ${r?.module}`);
999
+ }
1000
+ });
650
1001
  });
651
1002
  const clock = this.txb.sharedObjectRef(Protocol.CLOCK_OBJECT);
652
1003
  // rules: 'verify' & 'query' in turns; 'verify' at final end.