wowok 1.2.9 → 1.2.11
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/package.json +1 -1
- package/src/demand.ts +1 -1
- package/src/entity.ts +1 -1
- package/src/passport.ts +122 -36
- package/src/permission.ts +84 -0
- package/src/protocol.ts +3 -3
- package/src/utils.ts +5 -1
package/package.json
CHANGED
package/src/demand.ts
CHANGED
|
@@ -19,7 +19,7 @@ export class Demand {
|
|
|
19
19
|
let d = new Demand(protocol, bounty_type, permission)
|
|
20
20
|
d.object = Protocol.TXB_OBJECT(protocol.CurrentSession(), object)
|
|
21
21
|
return d
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
23
|
|
|
24
24
|
private constructor(protocol:Protocol, bounty_type:string, permission:PermissionObject) {
|
|
25
25
|
this.bounty_type = bounty_type;
|
package/src/entity.ts
CHANGED
package/src/passport.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type TransactionObjectInput, Inputs } from '@mysten/sui.js/transactions';
|
|
1
|
+
import { type TransactionObjectInput, Inputs, TransactionObjectArgument} from '@mysten/sui.js/transactions';
|
|
2
|
+
import { SuiObjectResponse } from '@mysten/sui.js/client';
|
|
2
3
|
import { FnCallType, GuardObject, Protocol, ContextType, OperatorType, Data_Type,
|
|
3
4
|
ValueType, SER_VALUE, IsValidOperatorType } from './protocol';
|
|
4
5
|
import { parse_object_type, array_unique, Bcs, ulebDecode, IsValidAddress, IsValidArray, OPTION_NONE, readOption, readOptionString } from './utils';
|
|
@@ -8,7 +9,7 @@ import { Guard } from './guard';
|
|
|
8
9
|
|
|
9
10
|
export type Guard_Query_Object = {
|
|
10
11
|
target: FnCallType, // object fnCall
|
|
11
|
-
object: TransactionObjectInput, // object
|
|
12
|
+
object: TransactionObjectInput | string, // object
|
|
12
13
|
types: string[], // object type
|
|
13
14
|
id: string, // object id
|
|
14
15
|
}
|
|
@@ -19,9 +20,11 @@ export interface QueryInfo {
|
|
|
19
20
|
type: number;
|
|
20
21
|
value_or_witness: string;
|
|
21
22
|
future?: string;
|
|
23
|
+
cmd?: number;
|
|
22
24
|
}
|
|
23
25
|
interface GuardInfo {
|
|
24
|
-
id: string;
|
|
26
|
+
id: string; // guard id
|
|
27
|
+
object: TransactionObjectInput;
|
|
25
28
|
query_list: (string | QueryInfo)[]; // object or witness object query
|
|
26
29
|
constant: QueryInfo[]; // witness in constant & ValueType.TYPE_ADDRESS(for Query)
|
|
27
30
|
input_witness: QueryInfo[]; // witness in input
|
|
@@ -41,26 +44,29 @@ export interface DeGuardData {
|
|
|
41
44
|
ret_type?: number;
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
export interface
|
|
47
|
+
export interface FutureFill {
|
|
45
48
|
guard: string;
|
|
46
49
|
index: number;
|
|
47
|
-
|
|
50
|
+
witness: string;
|
|
51
|
+
future?: string;
|
|
52
|
+
cmd?: number;
|
|
53
|
+
type?: string;
|
|
48
54
|
}
|
|
49
55
|
export interface PassportQuery {
|
|
50
|
-
guard:
|
|
56
|
+
guard: (string | TransactionObjectInput)[];
|
|
51
57
|
query: Guard_Query_Object[];
|
|
52
58
|
witness: Guard_Query_Object[];
|
|
53
59
|
}
|
|
54
60
|
export class GuardParser {
|
|
55
61
|
protected guard_list: GuardInfo[] = [];
|
|
56
62
|
protected protocol: Protocol;
|
|
57
|
-
protected guards:
|
|
63
|
+
protected guards: string[];
|
|
58
64
|
private index:number = 0;
|
|
59
65
|
private get_index() { return this.index++ }
|
|
60
66
|
|
|
61
67
|
private constructor(protocol: Protocol, guards: string[]) {
|
|
62
68
|
this.protocol = protocol ;
|
|
63
|
-
this.guards = guards
|
|
69
|
+
this.guards = guards;
|
|
64
70
|
}
|
|
65
71
|
guardlist = () => { return this.guard_list }
|
|
66
72
|
|
|
@@ -283,6 +289,7 @@ export class GuardParser {
|
|
|
283
289
|
switch (current.type) {
|
|
284
290
|
case OperatorType.TYPE_LOGIC_ALWAYS_TRUE:
|
|
285
291
|
current.ret_type = ValueType.TYPE_BOOL;
|
|
292
|
+
stack.push(current);
|
|
286
293
|
return;
|
|
287
294
|
case OperatorType.TYPE_LOGIC_NOT:
|
|
288
295
|
current.ret_type = ValueType.TYPE_BOOL;
|
|
@@ -416,7 +423,7 @@ export class GuardParser {
|
|
|
416
423
|
ERROR(Errors.Fail, 'OperateParamCount: type invalid ' + current.type);
|
|
417
424
|
}
|
|
418
425
|
|
|
419
|
-
|
|
426
|
+
/*
|
|
420
427
|
static CreateAsync = async (protocol: Protocol, guards: string[]) => {
|
|
421
428
|
if (!IsValidArray(guards, IsValidAddress)) {
|
|
422
429
|
ERROR(Errors.IsValidArray, 'guards');
|
|
@@ -426,6 +433,7 @@ export class GuardParser {
|
|
|
426
433
|
const me = new GuardParser(protocol, guards);
|
|
427
434
|
|
|
428
435
|
let res = await protocol.Query_Raw(guard_list);
|
|
436
|
+
console.log(res)
|
|
429
437
|
res.forEach((r) => {
|
|
430
438
|
let c = r.data?.content as any;
|
|
431
439
|
if (!c) return;
|
|
@@ -442,11 +450,70 @@ export class GuardParser {
|
|
|
442
450
|
})
|
|
443
451
|
return me
|
|
444
452
|
}
|
|
453
|
+
*/
|
|
454
|
+
private static Parse_Guard_Helper(guards: string[], res:SuiObjectResponse[]) {
|
|
455
|
+
const protocol = Protocol.Instance();
|
|
456
|
+
const me = new GuardParser(protocol, guards);
|
|
457
|
+
res.forEach((r) => {
|
|
458
|
+
let c = r.data?.content as any;
|
|
459
|
+
if (!c) return;
|
|
460
|
+
|
|
461
|
+
let index = protocol.WOWOK_OBJECTS_TYPE().findIndex(v => {return v.includes('guard::Guard') && v == c.type});
|
|
462
|
+
if (index == -1) return;
|
|
463
|
+
|
|
464
|
+
let info:GuardInfo = {id: c.fields.id.id, query_list:[], constant:[], input_witness:[], object:Inputs.ObjectRef(
|
|
465
|
+
{objectId:c.fields.id.id, digest:r.data?.digest??'', version:r.data?.version ?? ''}
|
|
466
|
+
)};
|
|
467
|
+
me.parse_constant(info, c.fields.constants); // MUST first
|
|
468
|
+
if (c.fields.input.type === (protocol.Package() + '::bcs::BCS')) {
|
|
469
|
+
me.parse_bcs(info, Uint8Array.from(c.fields.input.fields.bytes)); // second
|
|
470
|
+
}
|
|
471
|
+
me.guard_list.push(info);
|
|
472
|
+
})
|
|
473
|
+
return me
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
static Create = async (guards: string[], onGuardInfo?:(parser:GuardParser|undefined)=>void) => {
|
|
477
|
+
if (!IsValidArray(guards, IsValidAddress)) {
|
|
478
|
+
if (onGuardInfo) onGuardInfo(undefined);
|
|
479
|
+
return undefined;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
let guard_list = array_unique(guards);
|
|
483
|
+
const protocol = Protocol.Instance();
|
|
484
|
+
|
|
485
|
+
if (onGuardInfo) {
|
|
486
|
+
protocol.Query_Raw(guard_list)
|
|
487
|
+
.then((res) => { onGuardInfo(GuardParser.Parse_Guard_Helper(guards, res)); })
|
|
488
|
+
.catch((e) => { onGuardInfo(undefined); })
|
|
489
|
+
} else {
|
|
490
|
+
const res = await protocol.Query_Raw(guard_list);
|
|
491
|
+
return GuardParser.Parse_Guard_Helper(guards, res);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
future_fills = () : FutureFill[] => {
|
|
496
|
+
const ret : FutureFill[] = [];
|
|
497
|
+
this.guard_list.forEach((g) => {
|
|
498
|
+
g.query_list.forEach((v) => {
|
|
499
|
+
if (typeof(v) !== 'string') {
|
|
500
|
+
ret.push({guard:g.id, index:v.index, witness:v.value_or_witness, cmd:v.cmd});
|
|
501
|
+
}
|
|
502
|
+
})
|
|
503
|
+
// cmd already in query_list, so filter it out.
|
|
504
|
+
g.constant.filter((v)=>v.type === ContextType.TYPE_WITNESS_ID && v.cmd === undefined).forEach((v) => {
|
|
505
|
+
ret.push({guard:g.id, index:v.index, witness:v.value_or_witness});
|
|
506
|
+
})
|
|
507
|
+
g.input_witness.forEach((v) => {
|
|
508
|
+
ret.push({guard:g.id, index:v.index, witness:v.value_or_witness});
|
|
509
|
+
})
|
|
510
|
+
}); return ret;
|
|
511
|
+
}
|
|
445
512
|
|
|
446
513
|
parse_constant = (info:GuardInfo, constants:any) => {
|
|
447
514
|
constants.forEach((v:any) => {
|
|
448
515
|
if (v.type == (this.protocol.Package() + '::guard::Constant')) {
|
|
449
|
-
// ValueType.TYPE_ADDRESS: Query_Cmd maybe used the address, so save it for
|
|
516
|
+
// ValueType.TYPE_ADDRESS: Query_Cmd maybe used the address, so save it for querying
|
|
450
517
|
if (v.fields.type == ContextType.TYPE_WITNESS_ID || v.fields.type == ValueType.TYPE_ADDRESS) {
|
|
451
518
|
info.constant.push({identifier:v.fields.identifier, index:this.get_index(), type:v.fields.type,
|
|
452
519
|
value_or_witness:'0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(v.fields.value))});
|
|
@@ -507,14 +574,14 @@ export class GuardParser {
|
|
|
507
574
|
let type = arr.splice(0, 1);
|
|
508
575
|
if (type[0] == ValueType.TYPE_ADDRESS || type[0] == ContextType.TYPE_WITNESS_ID) {
|
|
509
576
|
let addr = '0x' + Bcs.getInstance().de(ValueType.TYPE_ADDRESS, Uint8Array.from(arr)).toString();
|
|
510
|
-
arr.splice(0, 33); // address + cmd
|
|
577
|
+
const offset = arr.splice(0, 33); // address + cmd
|
|
511
578
|
if (type[0] == ValueType.TYPE_ADDRESS) {
|
|
512
579
|
info.query_list.push(addr);
|
|
513
580
|
} else if (type[0] == ContextType.TYPE_WITNESS_ID){
|
|
514
|
-
info.query_list.push({index:this.get_index(), type:type[0], value_or_witness:addr});
|
|
581
|
+
info.query_list.push({index:this.get_index(), type:type[0], value_or_witness:addr, cmd:offset[offset.length-1]});
|
|
515
582
|
}
|
|
516
583
|
} else if (type[0] == ContextType.TYPE_CONSTANT) {
|
|
517
|
-
|
|
584
|
+
const identifer = arr.splice(0, 2); // key + cmd
|
|
518
585
|
let constant = info.constant.find((v) =>
|
|
519
586
|
(v.identifier == identifer[0]) &&
|
|
520
587
|
((v.type == ValueType.TYPE_ADDRESS) || (v.type == ContextType.TYPE_WITNESS_ID)));
|
|
@@ -522,7 +589,11 @@ export class GuardParser {
|
|
|
522
589
|
if (constant?.type == ValueType.TYPE_ADDRESS) {
|
|
523
590
|
info.query_list.push(constant.value_or_witness);
|
|
524
591
|
} else if (constant?.type == ContextType.TYPE_WITNESS_ID) {
|
|
525
|
-
|
|
592
|
+
const index = this.get_index();
|
|
593
|
+
info.query_list.push({identifier:identifer[0], type:constant.type, value_or_witness:constant.value_or_witness,
|
|
594
|
+
index:index, cmd:identifer[identifer.length-1]}); // query witness in constant
|
|
595
|
+
constant.cmd = identifer[identifer.length-1]; // mark this is a cmd in querylist(avoid multi input future by singer)
|
|
596
|
+
constant.index = index;
|
|
526
597
|
}
|
|
527
598
|
} else {
|
|
528
599
|
ERROR(Errors.Fail, 'constant type invalid');
|
|
@@ -535,7 +606,7 @@ export class GuardParser {
|
|
|
535
606
|
}
|
|
536
607
|
}
|
|
537
608
|
|
|
538
|
-
private get_object(guardid:string, info:QueryInfo, fill?:
|
|
609
|
+
private get_object(guardid:string, info:QueryInfo, fill?:FutureFill[]) : string {
|
|
539
610
|
let r = fill?.find(i => guardid == i.guard && i.index == info.index);
|
|
540
611
|
if (!r || !r.future) {
|
|
541
612
|
if (!info.future) {
|
|
@@ -547,12 +618,14 @@ export class GuardParser {
|
|
|
547
618
|
return info.future!
|
|
548
619
|
}
|
|
549
620
|
|
|
550
|
-
done = async (fill?:
|
|
621
|
+
done = async (fill?:FutureFill[], onPassportQueryReady?:(passport:PassportQuery | undefined)=>void) : Promise<PassportQuery | undefined>=> {
|
|
551
622
|
let objects: string[] = [];
|
|
552
623
|
this.guard_list.forEach((g) => {
|
|
553
|
-
|
|
624
|
+
// futures in constant table (all witness)
|
|
625
|
+
g.constant.filter(v => v.type == ContextType.TYPE_WITNESS_ID /*&& v.cmd === undefined*/).forEach((q) => {
|
|
554
626
|
objects.push(this.get_object(g.id, q, fill));
|
|
555
627
|
})
|
|
628
|
+
// objects to query
|
|
556
629
|
let list = g.query_list.map((q) => {
|
|
557
630
|
if (typeof(q) === "string") {
|
|
558
631
|
objects.push(q)
|
|
@@ -563,40 +636,56 @@ export class GuardParser {
|
|
|
563
636
|
return r
|
|
564
637
|
}
|
|
565
638
|
})
|
|
566
|
-
g.query_list = list;
|
|
639
|
+
g.query_list = list; // all to string to query
|
|
567
640
|
g.input_witness.forEach((q) => {
|
|
568
641
|
objects.push(this.get_object(g.id, q, fill));
|
|
569
642
|
})
|
|
570
643
|
})
|
|
571
644
|
|
|
572
|
-
|
|
573
|
-
|
|
645
|
+
if (onPassportQueryReady) {
|
|
646
|
+
this.protocol.Query_Raw(array_unique(objects), {showType:true}).then((res) => {
|
|
647
|
+
onPassportQueryReady(this.done_helper(res));
|
|
648
|
+
}).catch(e => {
|
|
649
|
+
console.log(e);
|
|
650
|
+
onPassportQueryReady(undefined);
|
|
651
|
+
})
|
|
652
|
+
return undefined;
|
|
653
|
+
} else {
|
|
654
|
+
const res = await this.protocol.Query_Raw(array_unique(objects), {showType:true});
|
|
655
|
+
return this.done_helper(res);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
private done_helper(res:SuiObjectResponse[]) {
|
|
574
660
|
let query: Guard_Query_Object[] = [];
|
|
575
661
|
let witness: Guard_Query_Object[] = [];
|
|
662
|
+
let guards: TransactionObjectInput[] = [];
|
|
576
663
|
this.guard_list.forEach(g => {
|
|
577
|
-
g.query_list.forEach(q => {
|
|
664
|
+
g.query_list.forEach(q => { // query list
|
|
578
665
|
let r = res.find(r => r.data?.objectId == q as string);
|
|
579
666
|
if (!r) { ERROR(Errors.Fail, 'query object not match')}
|
|
580
|
-
let object = this.object_query(r!.data);
|
|
667
|
+
let object = this.object_query(r!.data); // build passport query objects
|
|
581
668
|
if (!object) { ERROR(Errors.Fail, 'query object fail')}
|
|
582
669
|
query.push(object!);
|
|
583
670
|
})
|
|
584
|
-
res.forEach(q => {
|
|
585
|
-
let r1 = g.constant.find(v => v.future
|
|
586
|
-
let r2 = g.input_witness.find(v => v.future
|
|
671
|
+
res.forEach(q => { // witness(address & query) list
|
|
672
|
+
let r1 = g.constant.find(v => v.future === q.data?.objectId);
|
|
673
|
+
let r2 = g.input_witness.find(v => v.future === q.data?.objectId)
|
|
587
674
|
// not match r1 || r2 means query-cmd, not witness-cmd
|
|
588
675
|
if (r1 || r2) {
|
|
589
|
-
let object = this.object_query(q.data, 'witness');
|
|
676
|
+
let object = this.object_query(q.data, 'witness'); // witness address onchain check
|
|
590
677
|
if (!object) { ERROR(Errors.Fail, 'witness object fail') }
|
|
591
678
|
witness.push(object!);
|
|
592
679
|
}
|
|
593
680
|
})
|
|
681
|
+
guards.push(g.object);
|
|
594
682
|
})
|
|
595
683
|
|
|
596
|
-
return {guard:
|
|
684
|
+
return {guard:guards, query:query, witness:witness} as PassportQuery;
|
|
597
685
|
}
|
|
598
686
|
|
|
599
|
-
|
|
687
|
+
// create onchain query for objects : object, movecall-types, id
|
|
688
|
+
private object_query = (data: any, method:'guard_query'|'witness'='guard_query') : Guard_Query_Object | undefined=> {
|
|
600
689
|
for (let k = 0; k < this.protocol.WOWOK_OBJECTS_TYPE().length; k++) {
|
|
601
690
|
if (data.type.includes(this.protocol.WOWOK_OBJECTS_TYPE()[k]) ) { // type: pack::m::Object<...>
|
|
602
691
|
return { target:this.protocol.WOWOK_OBJECTS_PREFIX_TYPE()[k] + method as FnCallType,
|
|
@@ -620,13 +709,11 @@ export class Passport {
|
|
|
620
709
|
|
|
621
710
|
get_object () { return this.passport }
|
|
622
711
|
// return passport object used
|
|
623
|
-
|
|
712
|
+
// bObject(true) in cmd env; (false) in service env
|
|
713
|
+
constructor (protocol:Protocol, query:PassportQuery, bObject:boolean=false) {
|
|
624
714
|
if (!query.guard || query.guard.length > Passport.MAX_GUARD_COUNT) {
|
|
625
715
|
ERROR(Errors.InvalidParam, 'guards' )
|
|
626
716
|
}
|
|
627
|
-
if (!Protocol.IsValidObjects(query.guard)) {
|
|
628
|
-
ERROR(Errors.IsValidObjects, 'guards')
|
|
629
|
-
}
|
|
630
717
|
|
|
631
718
|
this.protocol = protocol;
|
|
632
719
|
let txb = protocol.CurrentSession();
|
|
@@ -639,7 +726,7 @@ export class Passport {
|
|
|
639
726
|
query.guard.forEach((g) => {
|
|
640
727
|
txb.moveCall({
|
|
641
728
|
target:protocol.PassportFn('guard_add') as FnCallType,
|
|
642
|
-
arguments:[this.passport,
|
|
729
|
+
arguments:[this.passport, txb.object(g)]
|
|
643
730
|
});
|
|
644
731
|
})
|
|
645
732
|
|
|
@@ -652,7 +739,7 @@ export class Passport {
|
|
|
652
739
|
})
|
|
653
740
|
})
|
|
654
741
|
|
|
655
|
-
// rules: 'verify' & 'query' in turns
|
|
742
|
+
// rules: 'verify' & 'query' in turns; 'verify' at final end.
|
|
656
743
|
query?.query.forEach((q) => {
|
|
657
744
|
let address = txb.moveCall({
|
|
658
745
|
target: protocol.PassportFn('passport_verify') as FnCallType,
|
|
@@ -660,11 +747,10 @@ export class Passport {
|
|
|
660
747
|
});
|
|
661
748
|
txb.moveCall({
|
|
662
749
|
target: q.target as FnCallType,
|
|
663
|
-
arguments: [ txb.object(q.object), this.passport, address ],
|
|
750
|
+
arguments: [ bObject ? txb.object(q.object) : txb.object(q.id), this.passport, address ],
|
|
664
751
|
typeArguments: q.types,
|
|
665
752
|
})
|
|
666
753
|
})
|
|
667
|
-
|
|
668
754
|
txb.moveCall({
|
|
669
755
|
target: protocol.PassportFn('passport_verify') as FnCallType,
|
|
670
756
|
arguments: [ this.passport, txb.object(Protocol.CLOCK_OBJECT) ]
|
package/src/permission.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { FnCallType, TxbObject, PermissionObject, PermissionAddress, GuardObject
|
|
|
3
3
|
import { array_unique, IsValidAddress, IsValidArray, IsValidDesription, IsValidUintLarge, Bcs, IsValidName} from './utils';
|
|
4
4
|
import { ERROR, Errors } from './exception';
|
|
5
5
|
import { ValueType } from './protocol';
|
|
6
|
+
import { Passport } from './passport';
|
|
6
7
|
|
|
7
8
|
export enum PermissionIndex {
|
|
8
9
|
repository = 100,
|
|
@@ -85,6 +86,19 @@ export interface PermissionInfoType {
|
|
|
85
86
|
guard?: string;
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
export interface PermissionAnswer {
|
|
90
|
+
who: string;
|
|
91
|
+
owner?: boolean;
|
|
92
|
+
admin?: boolean;
|
|
93
|
+
items?: PermissionAnswerItem[]; // items === undefined, while errors
|
|
94
|
+
}
|
|
95
|
+
export interface PermissionAnswerItem {
|
|
96
|
+
query: PermissionIndexType;
|
|
97
|
+
permission: boolean;
|
|
98
|
+
guard?: string;
|
|
99
|
+
}
|
|
100
|
+
export type OnPermissionAnswer = (answer: PermissionAnswer) => void;
|
|
101
|
+
|
|
88
102
|
export const PermissionInfo : PermissionInfoType[] = [
|
|
89
103
|
{index:PermissionIndex.repository, name:'Repository', description:'Launch new Repository', module: 'repository'},
|
|
90
104
|
{index:PermissionIndex.repository_set_description_set, name:'Description', description:'Set Repository description', module: 'repository'},
|
|
@@ -436,11 +450,81 @@ export class Permission {
|
|
|
436
450
|
arguments:[Protocol.TXB_OBJECT(txb, this.object), txb.pure(new_owner, BCS.ADDRESS)]
|
|
437
451
|
});
|
|
438
452
|
}
|
|
453
|
+
query_permissions(address_queried:string, permissions:PermissionIndexType[]) {
|
|
454
|
+
if (!IsValidAddress(address_queried)) {
|
|
455
|
+
ERROR(Errors.InvalidParam, 'query_permissions');
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (permissions.length === 0 || permissions.length > Permission.MAX_QUERY_COUNT) {
|
|
459
|
+
ERROR(Errors.InvalidParam, 'permissions count');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const txb = this.protocol.CurrentSession();
|
|
463
|
+
txb.moveCall({
|
|
464
|
+
target:this.protocol.PermissionFn('query_permissions') as FnCallType,
|
|
465
|
+
arguments:[Protocol.TXB_OBJECT(txb, this.object), txb.pure(address_queried, BCS.ADDRESS), txb.pure(permissions, 'vector<u64>')]
|
|
466
|
+
})
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
QueryPermissions(address_queried:string, permissions:PermissionIndexType[], onPermissionAnswer:OnPermissionAnswer, sender?:string) {
|
|
470
|
+
this.query_permissions(address_queried, permissions);
|
|
471
|
+
Protocol.Client().devInspectTransactionBlock({sender:sender ?? address_queried,
|
|
472
|
+
transactionBlock:this.protocol.CurrentSession()}).then((res) => {
|
|
473
|
+
if (res.results && res.results[0].returnValues && res.results[0].returnValues.length !== 3 ) {
|
|
474
|
+
onPermissionAnswer({who:address_queried});
|
|
475
|
+
return
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const perm = Bcs.getInstance().de(BCS.U8, Uint8Array.from((res.results as any)[0].returnValues[0][0]));
|
|
479
|
+
|
|
480
|
+
if (perm === Permission.PERMISSION_ADMIN || perm === Permission.PERMISSION_OWNER_AND_ADMIN) {
|
|
481
|
+
onPermissionAnswer({who:address_queried, admin:true, owner:perm%2===1, items:[]})
|
|
482
|
+
} else {
|
|
483
|
+
const perms = Bcs.getInstance().de('vector<u8>', Uint8Array.from((res.results as any)[0].returnValues[1][0]));
|
|
484
|
+
const guards = Bcs.getInstance().de('vector<address>', Uint8Array.from((res.results as any)[0].returnValues[2][0]));
|
|
485
|
+
if (perms.length !== permissions.length) {
|
|
486
|
+
onPermissionAnswer({who:address_queried});
|
|
487
|
+
return
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const items: PermissionAnswerItem[] = permissions.map((v, index) => {
|
|
491
|
+
const p = perms[index] === Permission.PERMISSION_QUERY_NONE ? false : true;
|
|
492
|
+
let g : any = undefined;
|
|
493
|
+
if (p && perms[index] < guards.length) {
|
|
494
|
+
g = '0x' + guards[perms[index] as number];
|
|
495
|
+
}
|
|
496
|
+
return {query:v, permission:p, guard:g}
|
|
497
|
+
})
|
|
498
|
+
onPermissionAnswer({who:address_queried, admin:false, owner:perm%2===1, items:items});
|
|
499
|
+
}
|
|
500
|
+
}).catch((e) => {
|
|
501
|
+
console.log(e);
|
|
502
|
+
onPermissionAnswer({who:address_queried});
|
|
503
|
+
})
|
|
504
|
+
}
|
|
505
|
+
static HasPermission(answer:PermissionAnswer|undefined, index:PermissionIndexType) : {has:boolean, guard?:string, owner?:boolean} {
|
|
506
|
+
if (answer) {
|
|
507
|
+
if (answer.admin) return {has:true, owner:answer.owner}; // admin
|
|
508
|
+
let i = answer.items?.find((v)=>v.query === index);
|
|
509
|
+
if (i) {
|
|
510
|
+
return {has:i.permission, guard:i.guard, owner:answer.owner};
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return {has:false}
|
|
514
|
+
}
|
|
439
515
|
|
|
440
516
|
static MAX_ADMIN_COUNT = 64;
|
|
441
517
|
static MAX_ENTITY_COUNT = 2000;
|
|
442
518
|
static MAX_PERMISSION_INDEX_COUNT = 200;
|
|
443
519
|
static MAX_PERSONAL_PERMISSION_COUNT = 200;
|
|
520
|
+
static MAX_QUERY_COUNT = 250; //
|
|
521
|
+
static PERMISSION_QUERY_NONE = 255;
|
|
522
|
+
static PERMISSION_QUERY_HAS = 254;
|
|
523
|
+
static PERMISSION_NORMAL = 0;
|
|
524
|
+
static PERMISSION_OWNER = 1;
|
|
525
|
+
static PERMISSION_ADMIN = 2;
|
|
526
|
+
static PERMISSION_OWNER_AND_ADMIN = 3;
|
|
527
|
+
|
|
444
528
|
static IsValidUserDefinedIndex = (index:number) => {
|
|
445
529
|
return index >= PermissionIndex.user_defined_start && IsValidUintLarge(index)
|
|
446
530
|
}
|
package/src/protocol.ts
CHANGED
|
@@ -191,9 +191,9 @@ export enum ENTRYPOINT {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
const TESTNET = {
|
|
194
|
-
package: "
|
|
195
|
-
wowok_object: '
|
|
196
|
-
entity_object: '
|
|
194
|
+
package: "0xc5bcb215cb4bc861203739b7378199969d4f60f5e8130fa1ebf87987bdee0b6a",
|
|
195
|
+
wowok_object: '0xe9fdb9c3ad7aa81ee32d3fc9618d6e69637111253445e864f898d29179d11a4d',
|
|
196
|
+
entity_object: '0xe1205f43507c943a82d5a67cb7d2b3b251ff4a80f3b38e815a78291ed53125ce',
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
const MAINNET = {
|
package/src/utils.ts
CHANGED
|
@@ -241,7 +241,11 @@ export class Bcs {
|
|
|
241
241
|
return new Uint8Array();
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
de(type:ValueType,
|
|
244
|
+
de(type:ValueType | string, data:Uint8Array | any) : any {
|
|
245
|
+
if (typeof(type) === 'string') {
|
|
246
|
+
return this.bcs.de(type, data);
|
|
247
|
+
}
|
|
248
|
+
|
|
245
249
|
switch(type) {
|
|
246
250
|
case ValueType.TYPE_BOOL:
|
|
247
251
|
return this.bcs.de(BCS.BOOL, data);
|