wowok 1.4.19 → 1.4.21

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,10 @@ 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
233
+ current.ret_type = ValueType.TYPE_ADDRESS;
234
+ stack.push(current);
235
+ return;
236
+ case ContextType.TYPE_GUARD:
429
237
  current.ret_type = ValueType.TYPE_ADDRESS;
430
238
  stack.push(current);
431
239
  return;
@@ -434,10 +242,6 @@ export class GuardParser {
434
242
  if (!v) ERROR(Errors.Fail, 'OperateParamCount: identifier invalid ' + current.type);
435
243
 
436
244
  current.ret_type = v?.type;
437
- if (v?.type == ContextType.TYPE_WITNESS_ID) {
438
- current.ret_type = ValueType.TYPE_ADDRESS;
439
- }
440
-
441
245
  stack.push(current);
442
246
  return;
443
247
 
@@ -445,52 +249,24 @@ export class GuardParser {
445
249
  ERROR(Errors.Fail, 'OperateParamCount: type invalid ' + current.type);
446
250
  }
447
251
 
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
252
  private static Parse_Guard_Helper(guards: string[], res:SuiObjectResponse[]) {
477
253
  const protocol = Protocol.Instance();
478
254
  const me = new GuardParser(guards);
479
255
  res.forEach((r) => {
480
- let c = r.data?.content as any;
481
- if (!c) return;
256
+ const c = r.data?.content as any;
257
+ if (!c) ERROR(Errors.Fail, 'Parse_Guard_Helper invalid content');
258
+
259
+ const index = protocol.WOWOK_OBJECTS_TYPE().findIndex(v => {return v.includes('guard::Guard') && v == c.type});
260
+ if (index === -1) ERROR(Errors.Fail, 'Parse_Guard_Helper invalid type: ' + c.type);
482
261
 
483
- let index = protocol.WOWOK_OBJECTS_TYPE().findIndex(v => {return v.includes('guard::Guard') && v == c.type});
484
- if (index == -1) return;
485
262
 
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
263
  if (c.fields.input.type === (protocol.Package() + '::bcs::BCS')) {
491
- me.parse_bcs(info, Uint8Array.from(c.fields.input.fields.bytes)); // second
264
+ const constants = GuardParser.parse_constant(c.fields.constants); // MUST first
265
+ const inputs = GuardParser.parse_bcs(constants, Uint8Array.from(c.fields.input.fields.bytes));
266
+ me.guard_list.push({id: c.fields.id.id, input:[...inputs], constant:[...constants], digest:r.data?.digest??'', version:r.data?.version ?? ''});
267
+ } else {
268
+ ERROR(Errors.Fail, 'Parse_Guard_Helper invalid package: '+c.fields.input.type);
492
269
  }
493
- me.guard_list.push(info);
494
270
  })
495
271
  return me
496
272
  }
@@ -502,10 +278,8 @@ export class GuardParser {
502
278
  }
503
279
 
504
280
  let guard_list = array_unique(guards);
505
- const protocol = Protocol.Instance();
506
-
507
281
  if (onGuardInfo) {
508
- protocol.Query_Raw(guard_list)
282
+ Protocol.Instance().Query_Raw(guard_list)
509
283
  .then((res) => {
510
284
  onGuardInfo(GuardParser.Parse_Guard_Helper(guards, res));
511
285
  }).catch((e) => {
@@ -513,53 +287,90 @@ export class GuardParser {
513
287
  onGuardInfo(undefined);
514
288
  })
515
289
  } else {
516
- const res = await protocol.Query_Raw(guard_list);
290
+ const res = await Protocol.Instance().Query_Raw(guard_list);
517
291
  return GuardParser.Parse_Guard_Helper(guards, res);
518
292
  }
519
293
  }
520
294
 
521
- future_fills = () : FutureFill[] => {
522
- const ret : FutureFill[] = [];
295
+ future_fills = () : WitnessFill[] => {
296
+ const ret : WitnessFill[] = [];
523
297
  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
298
  // 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});
299
+ //console.log(g.constant); console.log(g.input)
300
+ g.constant.filter((i)=>i.bWitness).forEach((v) => {
301
+ const cmd = g.input.filter((k)=>k.identifier === v.identifier && k.cmd !== undefined).map((k)=>k.cmd!);
302
+ let cited = 0;
303
+ g.input.forEach((k) => {
304
+ if (k.identifier === v.identifier) cited ++;
305
+ })
306
+ ret.push({guard:g.id, witness:undefined, identifier:v.identifier, type:v.type, cmd:cmd??[], cited:cited});
535
307
  })
536
308
  }); return ret;
537
309
  }
538
310
 
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
- }
311
+ static parse_constant = (constants:any) : DeGuardConstant[] => {
312
+ let ret : DeGuardConstant[] = [];
313
+ constants.forEach((c:any) => {
314
+ let v = c?.fields ?? c; // graphql dosnot 'fields', but rpcall has.
315
+ const data:Uint8Array = Uint8Array.from(v.value);
316
+ const type = data.slice(0, 1)[0];
317
+
318
+ if (v.bWitness) { //@ witness
319
+ ret.push({identifier:v.identifier, type:type, bWitness:v.bWitness, value:undefined});
320
+ return
550
321
  }
322
+
323
+ var value : any = data.slice(1);
324
+ switch (type) {
325
+ case ValueType.TYPE_ADDRESS:
326
+ value = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(value)).toString();
327
+ break;
328
+ case ValueType.TYPE_BOOL:
329
+ case ValueType.TYPE_U8:
330
+ case ValueType.TYPE_U64:
331
+ case ValueType.TYPE_U128:
332
+ case ValueType.TYPE_U256:
333
+ case ValueType.TYPE_VEC_U8:
334
+ case ValueType.TYPE_VEC_U64:
335
+ case ValueType.TYPE_VEC_U128:
336
+ case ValueType.TYPE_VEC_ADDRESS:
337
+ case ValueType.TYPE_VEC_BOOL:
338
+ case ValueType.TYPE_VEC_VEC_U8:
339
+ case ValueType.TYPE_OPTION_ADDRESS:
340
+ case ValueType.TYPE_OPTION_BOOL:
341
+ case ValueType.TYPE_OPTION_U128:
342
+ case ValueType.TYPE_OPTION_U8:
343
+ case ValueType.TYPE_OPTION_U64:
344
+ case ValueType.TYPE_OPTION_U256:
345
+ case ValueType.TYPE_VEC_U256:
346
+ case ValueType.TYPE_STRING:
347
+ case ValueType.TYPE_OPTION_STRING:
348
+ case ValueType.TYPE_OPTION_VEC_U8:
349
+ case ValueType.TYPE_VEC_STRING:
350
+ let de = SER_VALUE.find(s=>s.type==type);
351
+ if (!de) ERROR(Errors.Fail, 'GuardObject de error')
352
+ value = Bcs.getInstance().de(type as number, Uint8Array.from(value));
353
+ break;
354
+
355
+ default:
356
+ ERROR(Errors.Fail, 'GuardObject constant type invalid:' +type)
357
+ }
358
+ ret.push({identifier:v.identifier, type:type, bWitness:v.bWitness, value:value});
551
359
  });
552
- //console.log(info.constant)
360
+ return ret;
553
361
  }
554
362
 
555
- parse_bcs = (info:GuardInfo, chain_bytes: Uint8Array) => {
556
- var arr = [].slice.call(chain_bytes.reverse());
363
+ static parse_bcs = (constants: DeGuardConstant[], chain_bytes: Uint8Array) : DeGuardInput[] => {
364
+ let bytes = Uint8Array.from(chain_bytes);
365
+ let arr = [].slice.call(bytes.reverse());
366
+ let data : DeGuardInput[] = [];
557
367
  while (arr.length > 0) {
558
- var type : unknown = arr.shift() ;
559
- // console.log(type);
368
+ let type : unknown = arr.shift() ;
369
+ let value:any; let cmd:any; let identifier:any;
560
370
  switch (type as Data_Type) {
561
371
  case ContextType.TYPE_SIGNER:
562
372
  case ContextType.TYPE_CLOCK:
373
+ case ContextType.TYPE_GUARD:
563
374
  case OperatorType.TYPE_LOGIC_AS_U256_GREATER:
564
375
  case OperatorType.TYPE_LOGIC_AS_U256_GREATER_EQUAL:
565
376
  case OperatorType.TYPE_LOGIC_AS_U256_LESSER:
@@ -574,112 +385,164 @@ export class GuardParser {
574
385
  case OperatorType.TYPE_NUMBER_MOD:
575
386
  case OperatorType.TYPE_NUMBER_MULTIPLY:
576
387
  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]});
388
+ break;
389
+ case OperatorType.TYPE_LOGIC_AND: //@ with logics count
390
+ case OperatorType.TYPE_LOGIC_OR:
391
+ value = arr.shift()! as number;
392
+ break;
393
+ case ContextType.TYPE_CONSTANT:
394
+ identifier = arr.shift()! as number; // identifier
395
+ break;
396
+ case ValueType.TYPE_ADDRESS:
397
+ value = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
398
+ arr.splice(0, 32); // address
399
+ break;
400
+ case ValueType.TYPE_BOOL:
401
+ case ValueType.TYPE_U8:
402
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as number;
403
+ arr.shift();
404
+ break;
405
+ case ValueType.TYPE_U64:
406
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as number;
407
+ arr.splice(0, 8);
408
+ break;
409
+ case ValueType.TYPE_U128:
410
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as bigint;
411
+ arr.splice(0, 16);
412
+ break;
413
+ case ValueType.TYPE_U256:
414
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr)) as bigint;
415
+ arr.splice(0, 32);
416
+ break;
417
+ case ValueType.TYPE_VEC_U8:
418
+ case ValueType.TYPE_VEC_BOOL:
419
+ case ValueType.TYPE_STRING:
420
+ let r = ulebDecode(Uint8Array.from(arr));
421
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
422
+ arr.splice(0, r.value+r.length);
423
+ break;
424
+ case ValueType.TYPE_VEC_ADDRESS:
425
+ r = ulebDecode(Uint8Array.from(arr));
426
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
427
+ arr.splice(0, r.value*32+r.length);
428
+ break;
429
+ case ValueType.TYPE_VEC_U128:
430
+ r = ulebDecode(Uint8Array.from(arr));
431
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
432
+ arr.splice(0, r.value*16+r.length);
433
+ break;
434
+ case ValueType.TYPE_VEC_U256:
435
+ r = ulebDecode(Uint8Array.from(arr));
436
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
437
+ arr.splice(0, r.value*32+r.length);
438
+ break;
439
+ case ValueType.TYPE_VEC_U64:
440
+ r = ulebDecode(Uint8Array.from(arr));
441
+ value = Bcs.getInstance().de(type as ValueType, Uint8Array.from(arr));
442
+ arr.splice(0, r.value*8+r.length);
443
+ break;
444
+ case ValueType.TYPE_VEC_VEC_U8:
445
+ case ValueType.TYPE_VEC_STRING:
446
+ r = ulebDecode(Uint8Array.from(arr)); arr.splice(0, r.length);
447
+ let res = [];
448
+ for (let i = 0; i < r.value; i++) {
449
+ let r2 = ulebDecode(Uint8Array.from(arr));
450
+ res.push(Bcs.getInstance().de(ValueType.TYPE_VEC_U8, Uint8Array.from(arr)));
451
+ arr.splice(0, r2.length+r2.value);
619
452
  }
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)
453
+ value = res;
454
+ break;
455
+ case OperatorType.TYPE_QUERY:
456
+ let t = arr.splice(0, 1); // data-type
457
+ if (t[0] == ValueType.TYPE_ADDRESS) {
458
+ let addr = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
459
+ arr.splice(0, 32); // address
460
+ value = addr;
461
+ cmd = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2))) as number; // cmd(u16)
462
+ } else if (t[0] == ContextType.TYPE_CONSTANT) {
463
+ let id = arr.splice(0, 1); // key
464
+ let v = constants.find((v) =>
465
+ (v.identifier == id[0]) &&
466
+ ((v.type == ValueType.TYPE_ADDRESS)));
467
+ if (!v) { ERROR(Errors.Fail, 'GuardObject: indentifier not in constant')}
468
+ identifier = id[0];
469
+ cmd = Bcs.getInstance().de('u16', Uint8Array.from(arr.splice(0, 2))) as number; // cmd(u16)
470
+ } else {
471
+ ERROR(Errors.Fail, 'GuardObject: constant type invalid');
472
+ }
473
+ break;
474
+ case ValueType.TYPE_OPTION_ADDRESS:
475
+ let read = readOption(arr, ValueType.TYPE_ADDRESS);
476
+ value = read.value;
477
+ if (!read.bNone) arr.splice(0, 32);
478
+ break;
479
+ case ValueType.TYPE_OPTION_BOOL:
480
+ read = readOption(arr, ValueType.TYPE_BOOL);
481
+ value = read.value;
482
+ if (!read.bNone) arr.splice(0, 1);
483
+ break;
484
+ case ValueType.TYPE_OPTION_U8:
485
+ read = readOption(arr, ValueType.TYPE_U8);
486
+ value = read.value;
487
+ if (!read.bNone) arr.splice(0, 1);
488
+ break;
489
+ case ValueType.TYPE_OPTION_U128:
490
+ read = readOption(arr, ValueType.TYPE_U128);
491
+ value = read.value;
492
+ if (!read.bNone) arr.splice(0, 16);
493
+ break;
494
+ case ValueType.TYPE_OPTION_U256:
495
+ read = readOption(arr, ValueType.TYPE_U256);
496
+ value = read.value;
497
+ if (!read.bNone) arr.splice(0, 32);
498
+ break;
499
+ case ValueType.TYPE_OPTION_U64:
500
+ read = readOption(arr, ValueType.TYPE_U64);
501
+ value = read.value;
502
+ if (!read.bNone) arr.splice(0, 8);
503
+ break;
504
+ case ValueType.TYPE_OPTION_STRING:
505
+ read = readOptionString(arr); // splice in it
506
+ value = read.value;
507
+ break;
508
+ default:
509
+ ERROR(Errors.Fail, 'GuardObject: parse_bcs types ' + type)
643
510
  }
511
+ data.push({type:type as number, value:value, cmd:cmd, identifier:identifier});
644
512
  }
513
+ return data;
645
514
  }
646
515
 
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>=> {
516
+ done = async (fill?:WitnessFill[], onPassportQueryReady?:(passport:PassportQuery | undefined)=>void) : Promise<PassportQuery | undefined>=> {
660
517
  let objects: string[] = [];
518
+ // check all witness and get all objects to query.
661
519
  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));
520
+ g.constant.forEach((v)=> {
521
+ if (v.bWitness) {
522
+ const value = fill?.find((i)=>i.identifier === v.identifier);
523
+ if (!value) {
524
+ ERROR(Errors.Fail, 'done: invalid witness '+v.identifier);
525
+ } else {
526
+ v.value = value.witness;
527
+ }
528
+ }
665
529
  })
666
- // objects to query
667
- let list = g.query_list.map((q) => {
668
- if (typeof(q) === "string") {
669
- objects.push(q)
670
- return q
530
+ g.input.filter((v)=>v.cmd !== undefined).forEach((i)=> {
531
+ if (i.identifier !== undefined) {
532
+ const value = g.constant.find((c)=>c.identifier === i.identifier && c.type === ValueType.TYPE_ADDRESS);
533
+ if (!value || !IsValidAddress(value.value as string)) ERROR(Errors.Fail, 'done: invalid identifier '+i.identifier);
534
+ objects.push(value!.value);
671
535
  } else {
672
- let r = this.get_object(g.id, q, fill);
673
- objects.push(r);
674
- return r
536
+ objects.push(i.value);
675
537
  }
676
538
  })
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
539
  })
540
+
682
541
  if (onPassportQueryReady) {
542
+ if (objects.length === 0) {
543
+ onPassportQueryReady(this.done_helper([]));
544
+ return
545
+ }
683
546
  Protocol.Instance().Query_Raw(array_unique(objects), {showType:true}).then((res) => {
684
547
  onPassportQueryReady(this.done_helper(res));
685
548
  }).catch(e => {
@@ -688,37 +551,34 @@ export class GuardParser {
688
551
  })
689
552
  return undefined;
690
553
  } else {
691
- const res = await Protocol.Instance().Query_Raw(array_unique(objects), {showType:true});
554
+ let res:any[] = [];
555
+ if (objects.length > 0) {
556
+ res = await Protocol.Instance().Query_Raw(array_unique(objects), {showType:true});
557
+ }
692
558
  return this.done_helper(res);
693
559
  }
694
560
  }
695
561
 
696
562
  private done_helper(res:SuiObjectResponse[]) {
697
563
  let query: Guard_Query_Object[] = [];
698
- let witness: Guard_Query_Object[] = [];
699
564
  let guards: TransactionObjectInput[] = [];
700
565
  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);
566
+ guards.push(g.id);
567
+ g.input.filter((v)=>v.cmd !== undefined).forEach(q => { // query list
568
+ let id = q.value;
569
+ if (!id && q.identifier !== undefined) {
570
+ id = g.constant.find((i)=>i.identifier == q.identifier)?.value;
571
+ }
572
+
573
+ let r = res.find(r => r.data?.objectId == id);
703
574
  if (!r) { ERROR(Errors.Fail, 'query object not match')}
704
575
  let object = this.object_query(r!.data); // build passport query objects
705
576
  if (!object) { ERROR(Errors.Fail, 'query object fail')}
706
577
  query.push(object!);
707
578
  })
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
579
  })
720
580
 
721
- return {guard:guards, query:query, witness:witness} as PassportQuery;
581
+ return {query:query, info:this.guard_list} as PassportQuery;
722
582
  }
723
583
 
724
584
  // create onchain query for objects : object, movecall-types, id
@@ -748,7 +608,7 @@ export class Passport {
748
608
  // return passport object used
749
609
  // bObject(true) in cmd env; (false) in service env
750
610
  constructor (txb:TransactionBlock, query:PassportQuery, bObject:boolean=false) {
751
- if (!query.guard || query.guard.length > Passport.MAX_GUARD_COUNT) {
611
+ if (query.info.length === 0 || query.info.length > Passport.MAX_GUARD_COUNT) {
752
612
  ERROR(Errors.InvalidParam, 'guards' )
753
613
  }
754
614
 
@@ -759,21 +619,24 @@ export class Passport {
759
619
  });
760
620
 
761
621
  // add others guards, if any
762
- query.guard.forEach((g) => {
622
+ query.info.forEach((g) => {
623
+ const ids = g.constant.filter((i)=>i.bWitness).map((v)=>v.identifier);
624
+ const values = g.constant.filter((i)=>i.bWitness).map((v)=> {
625
+ const bcs = Bcs.getInstance().ser(v.type, v.value);
626
+ let r = new Uint8Array(bcs.length + 1);
627
+ r.set([v.type], 0); r.set(bcs, 1);
628
+ return [].slice.call(r)
629
+ });
630
+
631
+ const guard = g.version !== undefined && g.digest !== undefined ?
632
+ txb.objectRef({objectId:g.id, version:g.version, digest:g.digest}) :
633
+ txb.object(g.id);
634
+ //console.log(ids); console.log(values)
763
635
  this.txb.moveCall({
764
636
  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
- })
637
+ arguments:[this.passport, guard, this.txb.pure.vector('u8', [].slice.call(ids)),
638
+ this.txb.pure(Bcs.getInstance().ser('vector<vector<u8>>', [...values]))]
639
+ });
777
640
  })
778
641
 
779
642
  const clock = this.txb.sharedObjectRef(Protocol.CLOCK_OBJECT);
@@ -788,7 +651,7 @@ export class Passport {
788
651
  arguments: [ bObject ? this.txb.object(q.object) : this.txb.object(q.id), this.passport],
789
652
  typeArguments: q.types,
790
653
  })
791
- })
654
+ })
792
655
  this.txb.moveCall({
793
656
  target: Protocol.Instance().PassportFn('passport_verify') as FnCallType,
794
657
  arguments: [ this.passport, this.txb.object(clock) ]