wowok 1.4.19 → 1.4.20

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/src/passport.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { type TransactionObjectInput, Inputs, Transaction as TransactionBlock} from '@mysten/sui/transactions';
1
+ import { type TransactionObjectInput, Inputs, Transaction as TransactionBlock, TransactionResult, CallArg} from '@mysten/sui/transactions';
2
2
  import { SuiObjectResponse } from '@mysten/sui/client';
3
3
  import { FnCallType, GuardObject, Protocol, ContextType, OperatorType, Data_Type,
4
4
  ValueType, SER_VALUE, IsValidOperatorType } from './protocol';
5
- import { parse_object_type, array_unique, Bcs, ulebDecode, IsValidAddress, IsValidArray, OPTION_NONE, readOption, readOptionString } from './utils';
5
+ import { parse_object_type, array_unique, Bcs, ulebDecode, IsValidAddress, IsValidArray, insertAtHead, readOption, readOptionString } from './utils';
6
6
  import { ERROR, Errors } from './exception';
7
7
  import { Guard } from './guard';
8
8
 
@@ -13,49 +13,43 @@ export type Guard_Query_Object = {
13
13
  id: string, // object id
14
14
  }
15
15
 
16
- export interface QueryInfo {
17
- identifier?: number;
18
- index: number;
19
- type: number;
20
- value_or_witness: string;
21
- future?: string;
22
- cmd?: number;
23
- }
24
16
  interface GuardInfo {
25
17
  id: string; // guard id
26
- object: TransactionObjectInput;
27
- query_list: (string | QueryInfo)[]; // object or witness object query
28
- constant: QueryInfo[]; // witness in constant & ValueType.TYPE_ADDRESS(for Query)
29
- input_witness: QueryInfo[]; // witness in input
18
+ digest?: string;
19
+ version?: string | number;
20
+ input: DeGuardInput[]; // object or witness object query
21
+ constant: DeGuardConstant[]; // witness in constant & ValueType.TYPE_ADDRESS(for Query)
30
22
  }
31
23
 
32
24
  export interface DeGuardConstant {
33
25
  type: number; //
34
26
  value: any; //
35
- identifier?: number; // ID
27
+ bWitness: boolean;
28
+ identifier: number; // ID
36
29
  }
37
- export interface DeGuardData {
30
+ export interface DeGuardInput {
38
31
  type: number; //
39
32
  value?: any; //
40
33
  identifier?: number; // ID
41
34
  cmd?: number; //
35
+ }
36
+ export interface DeGuardData extends DeGuardInput {
42
37
  child: DeGuardData[];
43
38
  ret_type?: number;
44
39
  }
45
40
 
46
- export interface FutureFill {
41
+ export interface WitnessFill {
47
42
  guard: string;
48
- index: number;
49
- witness: string;
50
- future?: string;
51
- cmd?: number;
52
- type?: string;
43
+ witness: any;
44
+ cmd: number[];
45
+ cited: number;
46
+ type: ValueType;
53
47
  identifier?: number;
54
48
  }
49
+
55
50
  export interface PassportQuery {
56
- guard: (string | TransactionObjectInput)[];
57
51
  query: Guard_Query_Object[];
58
- witness: Guard_Query_Object[];
52
+ info: GuardInfo[];
59
53
  }
60
54
  export class GuardParser {
61
55
  protected guard_list: GuardInfo[] = [];
@@ -69,205 +63,16 @@ export class GuardParser {
69
63
  guardlist = () => { return this.guard_list }
70
64
 
71
65
  static DeGuardObject_FromData = (guard_constants:any, guard_input_bytes:any) : {object:DeGuardData, constant:DeGuardConstant[]} => {
72
- let constants : DeGuardConstant[] = [];
73
- guard_constants.forEach((c:any) => {
74
- let v = c?.fields ?? c; // graphql dosnot 'fields', but rpcall has.
75
- const data:Uint8Array = Uint8Array.from(v.value);
76
- const type = data.slice(0, 1)[0];
77
- var value : any = data.slice(1);
78
- switch (type) {
79
- case ContextType.TYPE_WITNESS_ID:
80
- case ValueType.TYPE_ADDRESS:
81
- value = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(value)).toString();
82
- break;
83
- case ValueType.TYPE_BOOL:
84
- case ValueType.TYPE_U8:
85
- case ValueType.TYPE_U64:
86
- case ValueType.TYPE_U128:
87
- case ValueType.TYPE_U256:
88
- case ValueType.TYPE_VEC_U8:
89
- case ValueType.TYPE_VEC_U64:
90
- case ValueType.TYPE_VEC_U128:
91
- case ValueType.TYPE_VEC_ADDRESS:
92
- case ValueType.TYPE_VEC_BOOL:
93
- case ValueType.TYPE_VEC_VEC_U8:
94
- case ValueType.TYPE_OPTION_ADDRESS:
95
- case ValueType.TYPE_OPTION_BOOL:
96
- case ValueType.TYPE_OPTION_U128:
97
- case ValueType.TYPE_OPTION_U8:
98
- case ValueType.TYPE_OPTION_U64:
99
- case ValueType.TYPE_OPTION_U256:
100
- case ValueType.TYPE_VEC_U256:
101
- case ValueType.TYPE_STRING:
102
- case ValueType.TYPE_OPTION_STRING:
103
- case ValueType.TYPE_OPTION_VEC_U8:
104
- case ValueType.TYPE_VEC_STRING:
105
- let de = SER_VALUE.find(s=>s.type==type);
106
- if (!de) ERROR(Errors.Fail, 'GuardObject de error')
107
- value = Bcs.getInstance().de(type as number, Uint8Array.from(value));
108
- break;
109
-
110
- default:
111
- ERROR(Errors.Fail, 'GuardObject constant type invalid:' +type)
112
- }
113
- constants.push({identifier:v.identifier, type:type, value:value});
114
- });
66
+ let constants : DeGuardConstant[] = GuardParser.parse_constant(guard_constants);
115
67
  // console.log(constants)
116
- let bytes = Uint8Array.from(guard_input_bytes);
117
- let arr = [].slice.call(bytes.reverse());
118
- let data : DeGuardData[] = [];
119
- while (arr.length > 0) {
120
- let type : unknown = arr.shift() ;
121
- let value:any; let cmd:any; let identifier:any;
122
- switch (type as Data_Type) {
123
- case ContextType.TYPE_SIGNER:
124
- case ContextType.TYPE_CLOCK:
125
- case OperatorType.TYPE_LOGIC_AS_U256_GREATER:
126
- case OperatorType.TYPE_LOGIC_AS_U256_GREATER_EQUAL:
127
- case OperatorType.TYPE_LOGIC_AS_U256_LESSER:
128
- case OperatorType.TYPE_LOGIC_AS_U256_LESSER_EQUAL:
129
- case OperatorType.TYPE_LOGIC_AS_U256_EQUAL:
130
- case OperatorType.TYPE_LOGIC_EQUAL:
131
- case OperatorType.TYPE_LOGIC_HAS_SUBSTRING:
132
- case OperatorType.TYPE_LOGIC_ALWAYS_TRUE:
133
- case OperatorType.TYPE_LOGIC_NOT:
134
- case OperatorType.TYPE_NUMBER_ADD:
135
- case OperatorType.TYPE_NUMBER_DEVIDE:
136
- case OperatorType.TYPE_NUMBER_MOD:
137
- case OperatorType.TYPE_NUMBER_MULTIPLY:
138
- case OperatorType.TYPE_NUMBER_SUBTRACT:
139
- break;
140
- case OperatorType.TYPE_LOGIC_AND: //@ with logics count
141
- case OperatorType.TYPE_LOGIC_OR:
142
- value = arr.shift()! as number;
143
- break;
144
- case ContextType.TYPE_CONSTANT:
145
- identifier = arr.shift()! as number; // identifier
146
- break;
147
- case ContextType.TYPE_WITNESS_ID: // add to constant
148
- case ValueType.TYPE_ADDRESS:
149
- value = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
150
- arr.splice(0, 32); // address
151
- break;
152
- case ValueType.TYPE_BOOL:
153
- case ValueType.TYPE_U8:
154
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as number;
155
- arr.shift();
156
- break;
157
- case ValueType.TYPE_U64:
158
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as number;
159
- arr.splice(0, 8);
160
- break;
161
- case ValueType.TYPE_U128:
162
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as bigint;
163
- arr.splice(0, 16);
164
- break;
165
- case ValueType.TYPE_U256:
166
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as bigint;
167
- arr.splice(0, 32);
168
- break;
169
- case ValueType.TYPE_VEC_U8:
170
- case ValueType.TYPE_VEC_BOOL:
171
- case ValueType.TYPE_STRING:
172
- let r = ulebDecode(Uint8Array.from(arr));
173
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
174
- arr.splice(0, r.value+r.length);
175
- break;
176
- case ValueType.TYPE_VEC_ADDRESS:
177
- r = ulebDecode(Uint8Array.from(arr));
178
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
179
- arr.splice(0, r.value*32+r.length);
180
- break;
181
- case ValueType.TYPE_VEC_U128:
182
- r = ulebDecode(Uint8Array.from(arr));
183
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
184
- arr.splice(0, r.value*16+r.length);
185
- break;
186
- case ValueType.TYPE_VEC_U256:
187
- r = ulebDecode(Uint8Array.from(arr));
188
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
189
- arr.splice(0, r.value*32+r.length);
190
- break;
191
- case ValueType.TYPE_VEC_U64:
192
- r = ulebDecode(Uint8Array.from(arr));
193
- value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
194
- arr.splice(0, r.value*8+r.length);
195
- break;
196
- case ValueType.TYPE_VEC_VEC_U8:
197
- case ValueType.TYPE_VEC_STRING:
198
- r = ulebDecode(Uint8Array.from(arr)); arr.splice(0, r.length);
199
- let res = [];
200
- for (let i = 0; i < r.value; i++) {
201
- let r2 = ulebDecode(Uint8Array.from(arr));
202
- res.push(Bcs.getInstance().de(ValueType.TYPE_VEC_U8, Uint8Array.from(arr)));
203
- arr.splice(0, r2.length+r2.value);
204
- }
205
- value = res;
206
- break;
207
- case OperatorType.TYPE_QUERY:
208
- let t = arr.splice(0, 1); // data-type
209
- if (t[0] == ValueType.TYPE_ADDRESS || t[0] == ContextType.TYPE_WITNESS_ID) {
210
- let addr = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
211
- arr.splice(0, 32); // address
212
- value = addr;
213
- cmd = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2))) as number; // cmd(u16)
214
- } else if (t[0] == ContextType.TYPE_CONSTANT) {
215
- let id = arr.splice(0, 1); // key
216
- let v = constants.find((v) =>
217
- (v.identifier == id[0]) &&
218
- ((v.type == ValueType.TYPE_ADDRESS) || (v.type == ContextType.TYPE_WITNESS_ID)));
219
- if (!v) { ERROR(Errors.Fail, 'GuardObject: indentifier not in constant')}
220
- identifier = id[0];
221
- cmd = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2))) as number; // cmd(u16)
222
- } else {
223
- ERROR(Errors.Fail, 'GuardObject: constant type invalid');
224
- }
225
- break;
226
- case ValueType.TYPE_OPTION_ADDRESS:
227
- let read = readOption(arr, ValueType.TYPE_ADDRESS);
228
- value = read.value;
229
- if (!read.bNone) arr.splice(0, 32);
230
- break;
231
- case ValueType.TYPE_OPTION_BOOL:
232
- read = readOption(arr, ValueType.TYPE_BOOL);
233
- value = read.value;
234
- if (!read.bNone) arr.splice(0, 1);
235
- break;
236
- case ValueType.TYPE_OPTION_U8:
237
- read = readOption(arr, ValueType.TYPE_U8);
238
- value = read.value;
239
- if (!read.bNone) arr.splice(0, 1);
240
- break;
241
- case ValueType.TYPE_OPTION_U128:
242
- read = readOption(arr, ValueType.TYPE_U128);
243
- value = read.value;
244
- if (!read.bNone) arr.splice(0, 16);
245
- break;
246
- case ValueType.TYPE_OPTION_U256:
247
- read = readOption(arr, ValueType.TYPE_U256);
248
- value = read.value;
249
- if (!read.bNone) arr.splice(0, 32);
250
- break;
251
- case ValueType.TYPE_OPTION_U64:
252
- read = readOption(arr, ValueType.TYPE_U64);
253
- value = read.value;
254
- if (!read.bNone) arr.splice(0, 8);
255
- break;
256
- case ValueType.TYPE_OPTION_STRING:
257
- read = readOptionString(arr); // splice in it
258
- value = read.value;
259
- break;
260
- default:
261
- ERROR(Errors.Fail, 'GuardObject: parse_bcs types ' + type)
262
- }
263
- data.push({type:type as number, value:value, cmd:cmd, identifier:identifier, child:[]});
264
- }
68
+
69
+ let inputs : DeGuardInput[] = GuardParser.parse_bcs(constants, guard_input_bytes);
265
70
 
266
71
  // console.log(data);
267
- if (!data || data.length == 0) ERROR(Errors.Fail, 'GuardObject: data parsed error');
72
+ if (!inputs || inputs.length == 0) ERROR(Errors.Fail, 'GuardObject: data parsed error');
268
73
  let stack: DeGuardData[] = [];
269
- data.forEach((d) => {
270
- this.ResolveData(constants, stack, d);
74
+ inputs.forEach((d) => {
75
+ GuardParser.ResolveData(constants, stack, {...d, child:[]});
271
76
  })
272
77
 
273
78
  if (stack.length != 1) {
@@ -425,7 +230,6 @@ export class GuardParser {
425
230
  stack.push(current);
426
231
  return;
427
232
  case ContextType.TYPE_SIGNER:
428
- case ContextType.TYPE_WITNESS_ID: /// notice!! convert witness type to address type
429
233
  current.ret_type = ValueType.TYPE_ADDRESS;
430
234
  stack.push(current);
431
235
  return;
@@ -434,10 +238,6 @@ export class GuardParser {
434
238
  if (!v) ERROR(Errors.Fail, 'OperateParamCount: identifier invalid ' + current.type);
435
239
 
436
240
  current.ret_type = v?.type;
437
- if (v?.type == ContextType.TYPE_WITNESS_ID) {
438
- current.ret_type = ValueType.TYPE_ADDRESS;
439
- }
440
-
441
241
  stack.push(current);
442
242
  return;
443
243
 
@@ -445,52 +245,24 @@ export class GuardParser {
445
245
  ERROR(Errors.Fail, 'OperateParamCount: type invalid ' + current.type);
446
246
  }
447
247
 
448
- /*
449
- static CreateAsync = async (protocol: Protocol, guards: string[]) => {
450
- if (!IsValidArray(guards, IsValidAddress)) {
451
- ERROR(Errors.IsValidArray, 'guards');
452
- }
453
-
454
- let guard_list = array_unique(guards);
455
- const me = new GuardParser(protocol, guards);
456
-
457
- let res = await protocol.Query_Raw(guard_list);
458
- console.log(res)
459
- res.forEach((r) => {
460
- let c = r.data?.content as any;
461
- if (!c) return;
462
-
463
- let index = protocol.WOWOK_OBJECTS_TYPE().findIndex(v => {return v.includes('guard::Guard') && v == c.type});
464
- if (index == -1) return;
465
-
466
- let info:GuardInfo = {id: c.fields.id.id, query_list:[], constant:[], input_witness:[]};
467
- me.parse_constant(info, c.fields.constants);
468
- if (c.fields.input.type == (protocol.Package() + '::bcs::BCS')) {
469
- me.parse_bcs(info, Uint8Array.from(c.fields.input.fields.bytes));
470
- }
471
- me.guard_list.push(info);
472
- })
473
- return me
474
- }
475
- */
476
248
  private static Parse_Guard_Helper(guards: string[], res:SuiObjectResponse[]) {
477
249
  const protocol = Protocol.Instance();
478
250
  const me = new GuardParser(guards);
479
251
  res.forEach((r) => {
480
- let c = r.data?.content as any;
481
- if (!c) return;
252
+ const c = r.data?.content as any;
253
+ if (!c) ERROR(Errors.Fail, 'Parse_Guard_Helper invalid content');
254
+
255
+ const index = protocol.WOWOK_OBJECTS_TYPE().findIndex(v => {return v.includes('guard::Guard') && v == c.type});
256
+ if (index === -1) ERROR(Errors.Fail, 'Parse_Guard_Helper invalid type: ' + c.type);
482
257
 
483
- let index = protocol.WOWOK_OBJECTS_TYPE().findIndex(v => {return v.includes('guard::Guard') && v == c.type});
484
- if (index == -1) return;
485
258
 
486
- let info:GuardInfo = {id: c.fields.id.id, query_list:[], constant:[], input_witness:[], object:Inputs.ObjectRef(
487
- {objectId:c.fields.id.id, digest:r.data?.digest??'', version:r.data?.version ?? ''}
488
- )};
489
- me.parse_constant(info, c.fields.constants); // MUST first
490
259
  if (c.fields.input.type === (protocol.Package() + '::bcs::BCS')) {
491
- me.parse_bcs(info, Uint8Array.from(c.fields.input.fields.bytes)); // second
260
+ const constants = GuardParser.parse_constant(c.fields.constants); // MUST first
261
+ const inputs = GuardParser.parse_bcs(constants, Uint8Array.from(c.fields.input.fields.bytes));
262
+ me.guard_list.push({id: c.fields.id.id, input:[...inputs], constant:[...constants], digest:r.data?.digest??'', version:r.data?.version ?? ''});
263
+ } else {
264
+ ERROR(Errors.Fail, 'Parse_Guard_Helper invalid package: '+c.fields.input.type);
492
265
  }
493
- me.guard_list.push(info);
494
266
  })
495
267
  return me
496
268
  }
@@ -502,10 +274,8 @@ export class GuardParser {
502
274
  }
503
275
 
504
276
  let guard_list = array_unique(guards);
505
- const protocol = Protocol.Instance();
506
-
507
277
  if (onGuardInfo) {
508
- protocol.Query_Raw(guard_list)
278
+ Protocol.Instance().Query_Raw(guard_list)
509
279
  .then((res) => {
510
280
  onGuardInfo(GuardParser.Parse_Guard_Helper(guards, res));
511
281
  }).catch((e) => {
@@ -513,50 +283,86 @@ export class GuardParser {
513
283
  onGuardInfo(undefined);
514
284
  })
515
285
  } else {
516
- const res = await protocol.Query_Raw(guard_list);
286
+ const res = await Protocol.Instance().Query_Raw(guard_list);
517
287
  return GuardParser.Parse_Guard_Helper(guards, res);
518
288
  }
519
289
  }
520
290
 
521
- future_fills = () : FutureFill[] => {
522
- const ret : FutureFill[] = [];
291
+ future_fills = () : WitnessFill[] => {
292
+ const ret : WitnessFill[] = [];
523
293
  this.guard_list.forEach((g) => {
524
- g.query_list.forEach((v) => {
525
- if (typeof(v) !== 'string') {
526
- ret.push({guard:g.id, index:v.index, witness:v.value_or_witness, cmd:v.cmd, identifier:v?.identifier});
527
- }
528
- })
529
294
  // cmd already in query_list, so filter it out.
530
- g.constant.filter((v)=>v.type === ContextType.TYPE_WITNESS_ID && v.cmd === undefined).forEach((v) => {
531
- ret.push({guard:g.id, index:v.index, witness:v.value_or_witness, identifier:v?.identifier});
532
- })
533
- g.input_witness.forEach((v) => {
534
- ret.push({guard:g.id, index:v.index, witness:v.value_or_witness, identifier:v?.identifier});
295
+ //console.log(g.constant); console.log(g.input)
296
+ g.constant.filter((i)=>i.bWitness).forEach((v) => {
297
+ const cmd = g.input.filter((k)=>k.identifier === v.identifier && k.cmd !== undefined).map((k)=>k.cmd!);
298
+ let cited = 0;
299
+ g.input.forEach((k) => {
300
+ if (k.identifier === v.identifier) cited ++;
301
+ })
302
+ ret.push({guard:g.id, witness:undefined, identifier:v.identifier, type:v.type, cmd:cmd??[], cited:cited});
535
303
  })
536
304
  }); return ret;
537
305
  }
538
306
 
539
- parse_constant = (info:GuardInfo, constants:any) => {
540
- constants.forEach((v:any) => {
541
- if (v.type == (Protocol.Instance().Package() + '::guard::Constant')) {
542
- // ValueType.TYPE_ADDRESS: Query_Cmd maybe used the address, so save it for querying
543
- const data = Uint8Array.from(v.fields.value);
544
- const type = data.slice(0, 1)[0];
545
- const value = data.slice(1);
546
- if (type == ContextType.TYPE_WITNESS_ID || type == ValueType.TYPE_ADDRESS) {
547
- info.constant.push({identifier:v.fields.identifier, index:this.get_index(), type:type,
548
- value_or_witness:'0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(value))});
549
- }
307
+ static parse_constant = (constants:any) : DeGuardConstant[] => {
308
+ let ret : DeGuardConstant[] = [];
309
+ constants.forEach((c:any) => {
310
+ let v = c?.fields ?? c; // graphql dosnot 'fields', but rpcall has.
311
+ const data:Uint8Array = Uint8Array.from(v.value);
312
+ const type = data.slice(0, 1)[0];
313
+
314
+ if (v.bWitness) { //@ witness
315
+ ret.push({identifier:v.identifier, type:type, bWitness:v.bWitness, value:undefined});
316
+ return
550
317
  }
318
+
319
+ var value : any = data.slice(1);
320
+ switch (type) {
321
+ case ValueType.TYPE_ADDRESS:
322
+ value = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(value)).toString();
323
+ break;
324
+ case ValueType.TYPE_BOOL:
325
+ case ValueType.TYPE_U8:
326
+ case ValueType.TYPE_U64:
327
+ case ValueType.TYPE_U128:
328
+ case ValueType.TYPE_U256:
329
+ case ValueType.TYPE_VEC_U8:
330
+ case ValueType.TYPE_VEC_U64:
331
+ case ValueType.TYPE_VEC_U128:
332
+ case ValueType.TYPE_VEC_ADDRESS:
333
+ case ValueType.TYPE_VEC_BOOL:
334
+ case ValueType.TYPE_VEC_VEC_U8:
335
+ case ValueType.TYPE_OPTION_ADDRESS:
336
+ case ValueType.TYPE_OPTION_BOOL:
337
+ case ValueType.TYPE_OPTION_U128:
338
+ case ValueType.TYPE_OPTION_U8:
339
+ case ValueType.TYPE_OPTION_U64:
340
+ case ValueType.TYPE_OPTION_U256:
341
+ case ValueType.TYPE_VEC_U256:
342
+ case ValueType.TYPE_STRING:
343
+ case ValueType.TYPE_OPTION_STRING:
344
+ case ValueType.TYPE_OPTION_VEC_U8:
345
+ case ValueType.TYPE_VEC_STRING:
346
+ let de = SER_VALUE.find(s=>s.type==type);
347
+ if (!de) ERROR(Errors.Fail, 'GuardObject de error')
348
+ value = Bcs.getInstance().de(type as number, Uint8Array.from(value));
349
+ break;
350
+
351
+ default:
352
+ ERROR(Errors.Fail, 'GuardObject constant type invalid:' +type)
353
+ }
354
+ ret.push({identifier:v.identifier, type:type, bWitness:v.bWitness, value:value});
551
355
  });
552
- //console.log(info.constant)
356
+ return ret;
553
357
  }
554
358
 
555
- parse_bcs = (info:GuardInfo, chain_bytes: Uint8Array) => {
556
- var arr = [].slice.call(chain_bytes.reverse());
359
+ static parse_bcs = (constants: DeGuardConstant[], chain_bytes: Uint8Array) : DeGuardInput[] => {
360
+ let bytes = Uint8Array.from(chain_bytes);
361
+ let arr = [].slice.call(bytes.reverse());
362
+ let data : DeGuardInput[] = [];
557
363
  while (arr.length > 0) {
558
- var type : unknown = arr.shift() ;
559
- // console.log(type);
364
+ let type : unknown = arr.shift() ;
365
+ let value:any; let cmd:any; let identifier:any;
560
366
  switch (type as Data_Type) {
561
367
  case ContextType.TYPE_SIGNER:
562
368
  case ContextType.TYPE_CLOCK:
@@ -574,112 +380,164 @@ export class GuardParser {
574
380
  case OperatorType.TYPE_NUMBER_MOD:
575
381
  case OperatorType.TYPE_NUMBER_MULTIPLY:
576
382
  case OperatorType.TYPE_NUMBER_SUBTRACT:
577
- break;
578
- case OperatorType.TYPE_LOGIC_AND: //@ logics count
579
- case OperatorType.TYPE_LOGIC_OR:
580
- arr.splice(0, 1); // identifier of constant
581
- break;
582
- case ContextType.TYPE_CONSTANT:
583
- arr.splice(0, 1); // identifier of constant
584
- break;
585
- case ContextType.TYPE_WITNESS_ID: // add to constant
586
- let addr = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
587
- arr.splice(0, 32); // address
588
- info.input_witness.push({index:this.get_index(), type:ContextType.TYPE_WITNESS_ID, value_or_witness:addr})
589
- break;
590
- case ValueType.TYPE_BOOL:
591
- case ValueType.TYPE_U8:
592
- arr.splice(0, 1); // identifier
593
- break;
594
- case ValueType.TYPE_ADDRESS:
595
- arr.splice(0, 32);
596
- break;
597
- case ValueType.TYPE_U64:
598
- arr.splice(0, 8);
599
- break;
600
- case ValueType.TYPE_U128:
601
- arr.splice(0, 16);
602
- break;
603
- case ValueType.TYPE_U256:
604
- arr.splice(0, 32);
605
- break;
606
- case ValueType.TYPE_VEC_U8:
607
- let {value, length} = ulebDecode(Uint8Array.from(arr));
608
- arr.splice(0, value+length);
609
- break;
610
- case OperatorType.TYPE_QUERY:
611
- let type = arr.splice(0, 1);
612
- if (type[0] == ValueType.TYPE_ADDRESS || type[0] == ContextType.TYPE_WITNESS_ID) {
613
- let addr = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
614
- const offset = arr.splice(0, 34); // address + cmd(U16)
615
- if (type[0] == ValueType.TYPE_ADDRESS) {
616
- info.query_list.push(addr);
617
- } else if (type[0] == ContextType.TYPE_WITNESS_ID){
618
- info.query_list.push({index:this.get_index(), type:type[0], value_or_witness:addr, cmd:offset[offset.length-1]});
383
+ break;
384
+ case OperatorType.TYPE_LOGIC_AND: //@ with logics count
385
+ case OperatorType.TYPE_LOGIC_OR:
386
+ value = arr.shift()! as number;
387
+ break;
388
+ case ContextType.TYPE_CONSTANT:
389
+ identifier = arr.shift()! as number; // identifier
390
+ break;
391
+ case ValueType.TYPE_ADDRESS:
392
+ value = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
393
+ arr.splice(0, 32); // address
394
+ break;
395
+ case ValueType.TYPE_BOOL:
396
+ case ValueType.TYPE_U8:
397
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as number;
398
+ arr.shift();
399
+ break;
400
+ case ValueType.TYPE_U64:
401
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as number;
402
+ arr.splice(0, 8);
403
+ break;
404
+ case ValueType.TYPE_U128:
405
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as bigint;
406
+ arr.splice(0, 16);
407
+ break;
408
+ case ValueType.TYPE_U256:
409
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as bigint;
410
+ arr.splice(0, 32);
411
+ break;
412
+ case ValueType.TYPE_VEC_U8:
413
+ case ValueType.TYPE_VEC_BOOL:
414
+ case ValueType.TYPE_STRING:
415
+ let r = ulebDecode(Uint8Array.from(arr));
416
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
417
+ arr.splice(0, r.value+r.length);
418
+ break;
419
+ case ValueType.TYPE_VEC_ADDRESS:
420
+ r = ulebDecode(Uint8Array.from(arr));
421
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
422
+ arr.splice(0, r.value*32+r.length);
423
+ break;
424
+ case ValueType.TYPE_VEC_U128:
425
+ r = ulebDecode(Uint8Array.from(arr));
426
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
427
+ arr.splice(0, r.value*16+r.length);
428
+ break;
429
+ case ValueType.TYPE_VEC_U256:
430
+ r = ulebDecode(Uint8Array.from(arr));
431
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
432
+ arr.splice(0, r.value*32+r.length);
433
+ break;
434
+ case ValueType.TYPE_VEC_U64:
435
+ r = ulebDecode(Uint8Array.from(arr));
436
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
437
+ arr.splice(0, r.value*8+r.length);
438
+ break;
439
+ case ValueType.TYPE_VEC_VEC_U8:
440
+ case ValueType.TYPE_VEC_STRING:
441
+ r = ulebDecode(Uint8Array.from(arr)); arr.splice(0, r.length);
442
+ let res = [];
443
+ for (let i = 0; i < r.value; i++) {
444
+ let r2 = ulebDecode(Uint8Array.from(arr));
445
+ res.push(Bcs.getInstance().de(ValueType.TYPE_VEC_U8, Uint8Array.from(arr)));
446
+ arr.splice(0, r2.length+r2.value);
619
447
  }
620
- } else if (type[0] == ContextType.TYPE_CONSTANT) {
621
- const identifer = arr.splice(0, 1); // key
622
- const cmd:number = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2)));
623
- let constant = info.constant.find((v) =>
624
- (v.identifier == identifer[0]) &&
625
- ((v.type == ValueType.TYPE_ADDRESS) || (v.type == ContextType.TYPE_WITNESS_ID)));
626
- if (!constant) { ERROR(Errors.Fail, 'indentifier not in constant')}
627
- if (constant?.type == ValueType.TYPE_ADDRESS) {
628
- info.query_list.push(constant.value_or_witness);
629
- } else if (constant?.type == ContextType.TYPE_WITNESS_ID) {
630
- const index = this.get_index();
631
- info.query_list.push({identifier:identifer[0], type:constant.type, value_or_witness:constant.value_or_witness,
632
- index:index, cmd:cmd}); // query witness in constant
633
- constant.cmd = cmd; // mark this is a cmd in querylist(avoid multi input future by singer)
634
- constant.index = index;
635
- }
636
- } else {
637
- ERROR(Errors.Fail, 'constant type invalid ' + type);
638
- }
639
-
640
- break;
641
- default:
642
- ERROR(Errors.Fail, 'parse_bcs types ' + arr)
448
+ value = res;
449
+ break;
450
+ case OperatorType.TYPE_QUERY:
451
+ let t = arr.splice(0, 1); // data-type
452
+ if (t[0] == ValueType.TYPE_ADDRESS) {
453
+ let addr = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
454
+ arr.splice(0, 32); // address
455
+ value = addr;
456
+ cmd = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2))) as number; // cmd(u16)
457
+ } else if (t[0] == ContextType.TYPE_CONSTANT) {
458
+ let id = arr.splice(0, 1); // key
459
+ let v = constants.find((v) =>
460
+ (v.identifier == id[0]) &&
461
+ ((v.type == ValueType.TYPE_ADDRESS)));
462
+ if (!v) { ERROR(Errors.Fail, 'GuardObject: indentifier not in constant')}
463
+ identifier = id[0];
464
+ cmd = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2))) as number; // cmd(u16)
465
+ } else {
466
+ ERROR(Errors.Fail, 'GuardObject: constant type invalid');
467
+ }
468
+ break;
469
+ case ValueType.TYPE_OPTION_ADDRESS:
470
+ let read = readOption(arr, ValueType.TYPE_ADDRESS);
471
+ value = read.value;
472
+ if (!read.bNone) arr.splice(0, 32);
473
+ break;
474
+ case ValueType.TYPE_OPTION_BOOL:
475
+ read = readOption(arr, ValueType.TYPE_BOOL);
476
+ value = read.value;
477
+ if (!read.bNone) arr.splice(0, 1);
478
+ break;
479
+ case ValueType.TYPE_OPTION_U8:
480
+ read = readOption(arr, ValueType.TYPE_U8);
481
+ value = read.value;
482
+ if (!read.bNone) arr.splice(0, 1);
483
+ break;
484
+ case ValueType.TYPE_OPTION_U128:
485
+ read = readOption(arr, ValueType.TYPE_U128);
486
+ value = read.value;
487
+ if (!read.bNone) arr.splice(0, 16);
488
+ break;
489
+ case ValueType.TYPE_OPTION_U256:
490
+ read = readOption(arr, ValueType.TYPE_U256);
491
+ value = read.value;
492
+ if (!read.bNone) arr.splice(0, 32);
493
+ break;
494
+ case ValueType.TYPE_OPTION_U64:
495
+ read = readOption(arr, ValueType.TYPE_U64);
496
+ value = read.value;
497
+ if (!read.bNone) arr.splice(0, 8);
498
+ break;
499
+ case ValueType.TYPE_OPTION_STRING:
500
+ read = readOptionString(arr); // splice in it
501
+ value = read.value;
502
+ break;
503
+ default:
504
+ ERROR(Errors.Fail, 'GuardObject: parse_bcs types ' + type)
643
505
  }
506
+ data.push({type:type as number, value:value, cmd:cmd, identifier:identifier});
644
507
  }
508
+ return data;
645
509
  }
646
510
 
647
- private get_object(guardid:string, info:QueryInfo, fill?:FutureFill[]) : string {
648
- let r = fill?.find(i => guardid == i.guard && i.index == info.index);
649
- if (!r || !r.future) {
650
- if (!info.future) {
651
- ERROR(Errors.InvalidParam, 'index invalid for fill')
652
- }
653
- } else {
654
- info.future = r!.future;
655
- }
656
- return info.future!
657
- }
658
-
659
- done = async (fill?:FutureFill[], onPassportQueryReady?:(passport:PassportQuery | undefined)=>void) : Promise<PassportQuery | undefined>=> {
511
+ done = async (fill?:WitnessFill[], onPassportQueryReady?:(passport:PassportQuery | undefined)=>void) : Promise<PassportQuery | undefined>=> {
660
512
  let objects: string[] = [];
513
+ // check all witness and get all objects to query.
661
514
  this.guard_list.forEach((g) => {
662
- // futures in constant table (all witness)
663
- g.constant.filter(v => v.type == ContextType.TYPE_WITNESS_ID /*&& v.cmd === undefined*/).forEach((q) => {
664
- objects.push(this.get_object(g.id, q, fill));
515
+ g.constant.forEach((v)=> {
516
+ if (v.bWitness) {
517
+ const value = fill?.find((i)=>i.identifier === v.identifier);
518
+ if (!value) {
519
+ ERROR(Errors.Fail, 'done: invalid witness '+v.identifier);
520
+ } else {
521
+ v.value = value.witness;
522
+ }
523
+ }
665
524
  })
666
- // objects to query
667
- let list = g.query_list.map((q) => {
668
- if (typeof(q) === "string") {
669
- objects.push(q)
670
- return q
525
+ g.input.filter((v)=>v.cmd !== undefined).forEach((i)=> {
526
+ if (i.identifier !== undefined) {
527
+ const value = g.constant.find((c)=>c.identifier === i.identifier && c.type === ValueType.TYPE_ADDRESS);
528
+ if (!value || !IsValidAddress(value.value as string)) ERROR(Errors.Fail, 'done: invalid identifier '+i.identifier);
529
+ objects.push(value!.value);
671
530
  } else {
672
- let r = this.get_object(g.id, q, fill);
673
- objects.push(r);
674
- return r
531
+ objects.push(i.value);
675
532
  }
676
533
  })
677
- g.query_list = list; // all to string to query
678
- g.input_witness.forEach((q) => {
679
- objects.push(this.get_object(g.id, q, fill));
680
- })
681
534
  })
535
+
682
536
  if (onPassportQueryReady) {
537
+ if (objects.length === 0) {
538
+ onPassportQueryReady(this.done_helper([]));
539
+ return
540
+ }
683
541
  Protocol.Instance().Query_Raw(array_unique(objects), {showType:true}).then((res) => {
684
542
  onPassportQueryReady(this.done_helper(res));
685
543
  }).catch(e => {
@@ -688,37 +546,34 @@ export class GuardParser {
688
546
  })
689
547
  return undefined;
690
548
  } else {
691
- const res = await Protocol.Instance().Query_Raw(array_unique(objects), {showType:true});
549
+ let res:any[] = [];
550
+ if (objects.length > 0) {
551
+ res = await Protocol.Instance().Query_Raw(array_unique(objects), {showType:true});
552
+ }
692
553
  return this.done_helper(res);
693
554
  }
694
555
  }
695
556
 
696
557
  private done_helper(res:SuiObjectResponse[]) {
697
558
  let query: Guard_Query_Object[] = [];
698
- let witness: Guard_Query_Object[] = [];
699
559
  let guards: TransactionObjectInput[] = [];
700
560
  this.guard_list.forEach(g => {
701
- g.query_list.forEach(q => { // query list
702
- let r = res.find(r => r.data?.objectId == q as string);
561
+ guards.push(g.id);
562
+ g.input.filter((v)=>v.cmd !== undefined).forEach(q => { // query list
563
+ let id = q.value;
564
+ if (!id && q.identifier !== undefined) {
565
+ id = g.constant.find((i)=>i.identifier == q.identifier)?.value;
566
+ }
567
+
568
+ let r = res.find(r => r.data?.objectId == id);
703
569
  if (!r) { ERROR(Errors.Fail, 'query object not match')}
704
570
  let object = this.object_query(r!.data); // build passport query objects
705
571
  if (!object) { ERROR(Errors.Fail, 'query object fail')}
706
572
  query.push(object!);
707
573
  })
708
- res.forEach(q => { // witness(address & query) list
709
- let r1 = g.constant.find(v => v.future === q.data?.objectId);
710
- let r2 = g.input_witness.find(v => v.future === q.data?.objectId)
711
- // not match r1 || r2 means query-cmd, not witness-cmd
712
- if (r1 || r2) {
713
- let object = this.object_query(q.data, 'witness'); // witness address onchain check
714
- if (!object) { ERROR(Errors.Fail, 'witness object fail') }
715
- witness.push(object!);
716
- }
717
- })
718
- guards.push(g.object);
719
574
  })
720
575
 
721
- return {guard:guards, query:query, witness:witness} as PassportQuery;
576
+ return {query:query, info:this.guard_list} as PassportQuery;
722
577
  }
723
578
 
724
579
  // create onchain query for objects : object, movecall-types, id
@@ -748,7 +603,7 @@ export class Passport {
748
603
  // return passport object used
749
604
  // bObject(true) in cmd env; (false) in service env
750
605
  constructor (txb:TransactionBlock, query:PassportQuery, bObject:boolean=false) {
751
- if (!query.guard || query.guard.length > Passport.MAX_GUARD_COUNT) {
606
+ if (query.info.length === 0 || query.info.length > Passport.MAX_GUARD_COUNT) {
752
607
  ERROR(Errors.InvalidParam, 'guards' )
753
608
  }
754
609
 
@@ -759,21 +614,24 @@ export class Passport {
759
614
  });
760
615
 
761
616
  // add others guards, if any
762
- query.guard.forEach((g) => {
617
+ query.info.forEach((g) => {
618
+ const ids = g.constant.filter((i)=>i.bWitness).map((v)=>v.identifier);
619
+ const values = g.constant.filter((i)=>i.bWitness).map((v)=> {
620
+ const bcs = Bcs.getInstance().ser(v.type, v.value);
621
+ let r = new Uint8Array(bcs.length + 1);
622
+ r.set([v.type], 0); r.set(bcs, 1);
623
+ return [].slice.call(r)
624
+ });
625
+
626
+ const guard = g.version !== undefined && g.digest !== undefined ?
627
+ txb.objectRef({objectId:g.id, version:g.version, digest:g.digest}) :
628
+ txb.object(g.id);
629
+ //console.log(ids); console.log(values)
763
630
  this.txb.moveCall({
764
631
  target:Protocol.Instance().PassportFn('guard_add') as FnCallType,
765
- arguments:[this.passport, this.txb.object(g)]
766
- });
767
- })
768
-
769
- console.log(query)
770
- // witness
771
- query?.witness.forEach((w) => {
772
- this.txb.moveCall({
773
- target: w.target as FnCallType,
774
- arguments: [this.passport, this.txb.object(w.object)],
775
- typeArguments: w.types,
776
- })
632
+ arguments:[this.passport, guard, this.txb.pure.vector('u8', [].slice.call(ids)),
633
+ this.txb.pure(Bcs.getInstance().ser('vector<vector<u8>>', [...values]))]
634
+ });
777
635
  })
778
636
 
779
637
  const clock = this.txb.sharedObjectRef(Protocol.CLOCK_OBJECT);
@@ -788,7 +646,7 @@ export class Passport {
788
646
  arguments: [ bObject ? this.txb.object(q.object) : this.txb.object(q.id), this.passport],
789
647
  typeArguments: q.types,
790
648
  })
791
- })
649
+ })
792
650
  this.txb.moveCall({
793
651
  target: Protocol.Instance().PassportFn('passport_verify') as FnCallType,
794
652
  arguments: [ this.passport, this.txb.object(clock) ]