wowok_agent 0.1.3 → 0.1.5
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/account.ts +65 -2
- package/src/cache.ts +37 -8
- package/src/call/arbitration.ts +12 -4
- package/src/call/base.ts +28 -8
- package/src/call/demand.ts +13 -15
- package/src/call/guard.ts +0 -3
- package/src/call/machine.ts +1 -2
- package/src/call/personal.ts +29 -29
- package/src/call/service.ts +9 -12
- package/src/call/treasury.ts +11 -3
- package/src/entity.ts +60 -0
- package/src/index.ts +2 -0
- package/src/objects.ts +27 -38
- package/src/permission.ts +1 -1
package/package.json
CHANGED
package/src/account.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as os from 'os';
|
|
4
|
-
import { Ed25519Keypair, fromHEX, toHEX, decodeSuiPrivateKey } from 'wowok';
|
|
4
|
+
import { Ed25519Keypair, fromHEX, toHEX, decodeSuiPrivateKey, Protocol, CoinBalance, CoinStruct, TransactionResult, TransactionBlock, TransactionArgument, ERROR, Errors } from 'wowok';
|
|
5
5
|
import { getFaucetHost, requestSuiFromFaucetV0, requestSuiFromFaucetV1 } from 'wowok';
|
|
6
6
|
export interface AccountData {
|
|
7
7
|
name: string;
|
|
@@ -217,4 +217,67 @@ export class Account {
|
|
|
217
217
|
})
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
|
|
220
|
+
|
|
221
|
+
// token_type is 0x2::sui::SUI, if not specified.
|
|
222
|
+
balance = async (name?:string, token_type?:string) : Promise<CoinBalance | undefined> => {
|
|
223
|
+
const addr = this.get_address(name);
|
|
224
|
+
if (addr) {
|
|
225
|
+
return await Protocol.Client().getBalance({owner: addr, coinType:token_type});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// token_type is 0x2::sui::SUI, if not specified.
|
|
230
|
+
coin = async (name?:string, token_type?:string) : Promise<CoinStruct[] | undefined> => {
|
|
231
|
+
const addr = this.get_address(name);
|
|
232
|
+
if (addr) {
|
|
233
|
+
return (await Protocol.Client().getCoins({owner: addr, coinType:token_type})).data;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
get_coin_object = async (txb: TransactionBlock, balance_required:string | bigint | number, name?:string, token_type?:string) : Promise<TransactionResult | undefined> => {
|
|
238
|
+
const addr = this.get_address(name);
|
|
239
|
+
const b = BigInt(balance_required);
|
|
240
|
+
|
|
241
|
+
if (addr && b > BigInt(0)) {
|
|
242
|
+
if (!token_type || token_type === '0x2::sui::SUI' || token_type === '0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI') {
|
|
243
|
+
return txb.splitCoins(txb.gas, [balance_required]);
|
|
244
|
+
} else {
|
|
245
|
+
const r = await Protocol.Client().getCoins({owner: addr, coinType:token_type});
|
|
246
|
+
const objects : string[] = []; var current = BigInt(0);
|
|
247
|
+
for (let i = 0; i < r.data.length; ++ i) {
|
|
248
|
+
current += BigInt(r.data[i].balance);
|
|
249
|
+
objects.push(r.data[i].coinObjectId);
|
|
250
|
+
if (current >= b) {
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (objects.length === 1) {
|
|
256
|
+
return txb.splitCoins(objects[0], [b]);
|
|
257
|
+
} else {
|
|
258
|
+
const ret = objects.pop()!;
|
|
259
|
+
txb.mergeCoins(ret, objects);
|
|
260
|
+
return txb.splitCoins(ret, [b])
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
coin_with_balance = async(balance_required:string | bigint | number, account?:string, token_type?:string) : Promise<string | undefined> => {
|
|
266
|
+
const pair = this.get_pair(account, true);
|
|
267
|
+
if (!pair) ERROR(Errors.Fail, 'account invalid')
|
|
268
|
+
|
|
269
|
+
const txb = new TransactionBlock();
|
|
270
|
+
const res = await Account.Instance().get_coin_object(txb, balance_required, account, token_type);
|
|
271
|
+
if (res) {
|
|
272
|
+
txb.transferObjects([(res as unknown) as TransactionArgument], pair?.toSuiAddress()!)
|
|
273
|
+
const r = await Protocol.Client().signAndExecuteTransaction({
|
|
274
|
+
transaction: txb,
|
|
275
|
+
signer: pair!,
|
|
276
|
+
options:{showObjectChanges:true},
|
|
277
|
+
});
|
|
278
|
+
const t = token_type ?? '0x2::sui::SUI';
|
|
279
|
+
return ((r as any)?.objectChanges.find((v:any) => v?.type === 'created' && (v?.objectType as string).includes(t)) as any)?.objectId;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
package/src/cache.ts
CHANGED
|
@@ -1,27 +1,52 @@
|
|
|
1
1
|
|
|
2
2
|
import { Protocol } from "wowok";
|
|
3
3
|
|
|
4
|
+
export type CacheExpire = number | 'INFINITE';
|
|
5
|
+
|
|
6
|
+
export interface CachedData {
|
|
7
|
+
expire: number | 'INFINITE';
|
|
8
|
+
data: string | any;
|
|
9
|
+
}
|
|
10
|
+
|
|
4
11
|
export abstract class CacheData {
|
|
5
12
|
constructor(expire: number) { this.expire = expire; } // 10m default
|
|
6
13
|
abstract load(key: string) : string | null | undefined;
|
|
7
14
|
abstract save(key: string, data:string) : void;
|
|
15
|
+
abstract remove(key: string) : void;
|
|
8
16
|
expire_time() {return this.expire};
|
|
9
17
|
protected expire;
|
|
10
18
|
}
|
|
11
19
|
|
|
12
|
-
export
|
|
13
|
-
|
|
20
|
+
export enum CacheName {
|
|
21
|
+
object = 'OBJECT',
|
|
22
|
+
resource = 'RESOURCE',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const OBJECT_KEY = (object_address: string) : string => {
|
|
26
|
+
return object_address + Protocol.Instance().package('wowok_origin') + CacheName.object + '-V2';
|
|
27
|
+
}
|
|
28
|
+
export const PERSONAL_RESOURCE_KEY = (person_address: string) : string => {
|
|
29
|
+
return person_address + Protocol.Instance().package('wowok_origin') + CacheName.resource + '-V2';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PersonalResouceCache {
|
|
33
|
+
address: string;
|
|
34
|
+
resource: string;
|
|
35
|
+
time_expire?: CacheExpire;
|
|
14
36
|
}
|
|
15
37
|
|
|
16
38
|
export class MemeryCache extends CacheData {
|
|
17
39
|
constructor(expire: number = 10000) {super(expire)}
|
|
18
|
-
protected data = new Map<string, string
|
|
40
|
+
protected data = new Map<string, string>();
|
|
19
41
|
load(key: string) : string | null | undefined {
|
|
20
42
|
return this.data.get(key)
|
|
21
43
|
}
|
|
22
44
|
save(key: string, data:string) : void {
|
|
23
45
|
this.data.set(key, data);
|
|
24
46
|
}
|
|
47
|
+
remove(key: string) : void {
|
|
48
|
+
this.data.delete(key)
|
|
49
|
+
}
|
|
25
50
|
}
|
|
26
51
|
|
|
27
52
|
export class LocalStorageCache extends CacheData {
|
|
@@ -32,11 +57,14 @@ export class LocalStorageCache extends CacheData {
|
|
|
32
57
|
save(key: string, data:string) : void {
|
|
33
58
|
return localStorage.setItem(key, data)
|
|
34
59
|
}
|
|
60
|
+
remove(key: string) : void {
|
|
61
|
+
return localStorage.removeItem(key)
|
|
62
|
+
}
|
|
35
63
|
}
|
|
36
64
|
|
|
37
65
|
export class WowokCache {
|
|
38
66
|
static _instance: any;
|
|
39
|
-
private cache:
|
|
67
|
+
private cache: Map<string, CacheData | undefined> = new Map();
|
|
40
68
|
|
|
41
69
|
constructor() {}
|
|
42
70
|
static Instance() : WowokCache {
|
|
@@ -45,10 +73,11 @@ export class WowokCache {
|
|
|
45
73
|
}; return WowokCache._instance
|
|
46
74
|
}
|
|
47
75
|
|
|
48
|
-
set(cache:CacheData) {
|
|
49
|
-
this.cache
|
|
76
|
+
set(name:string | CacheName, cache:CacheData | undefined) {
|
|
77
|
+
this.cache.set(name, cache);
|
|
50
78
|
}
|
|
51
|
-
|
|
52
|
-
|
|
79
|
+
|
|
80
|
+
get(name:string | CacheName) : CacheData | undefined {
|
|
81
|
+
return this.cache.get(name);
|
|
53
82
|
}
|
|
54
83
|
}
|
package/src/call/arbitration.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { TransactionBlock, CallResponse, IsValidArgType} from 'wowok';
|
|
1
|
+
import { TransactionBlock, CallResponse, IsValidArgType, TransactionResult} from 'wowok';
|
|
2
2
|
import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIndex, PermissionIndexType, Treasury,
|
|
3
3
|
Arbitration, Dispute, Feedback, Vote, VotingGuard, WithdrawFee, WitnessFill
|
|
4
4
|
} from 'wowok';
|
|
5
5
|
import { query_objects, ObjectArbitration, } from '../objects';
|
|
6
|
-
import { CallBase, CallResult } from "./base";
|
|
6
|
+
import { CallBase, CallResult, AddressMark } from "./base";
|
|
7
7
|
|
|
8
8
|
export interface CallArbitration_Data {
|
|
9
9
|
object?: string; // undefined for creating a new object
|
|
10
10
|
permission?: string;
|
|
11
|
+
mark?:AddressMark;
|
|
11
12
|
type_parameter?: string;
|
|
12
13
|
permission_new?: string;
|
|
13
14
|
description?: string;
|
|
@@ -101,7 +102,7 @@ export class CallArbitration extends CallBase {
|
|
|
101
102
|
}
|
|
102
103
|
return this.exec(account);
|
|
103
104
|
}
|
|
104
|
-
protected async operate(txb:TransactionBlock, passport?:PassportObject) {
|
|
105
|
+
protected async operate(txb:TransactionBlock, passport?:PassportObject, account?:string) {
|
|
105
106
|
let obj : Arbitration | undefined ; let permission: any; let withdraw_treasury:any;
|
|
106
107
|
if (!this.data.object) {
|
|
107
108
|
if (!this.data?.permission || !IsValidAddress(this.data?.permission)) {
|
|
@@ -176,8 +177,15 @@ export class CallArbitration extends CallBase {
|
|
|
176
177
|
if (permission) {
|
|
177
178
|
permission.launch();
|
|
178
179
|
}
|
|
180
|
+
var mark : TransactionResult | string | undefined ;
|
|
179
181
|
if (!this.data.object) {
|
|
180
|
-
obj?.launch();
|
|
182
|
+
mark = obj?.launch();
|
|
183
|
+
} else {
|
|
184
|
+
mark = this.data.object;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (this.data?.mark !== undefined) {
|
|
188
|
+
this.mark(txb, mark, this.data?.mark, account)
|
|
181
189
|
}
|
|
182
190
|
}
|
|
183
191
|
}
|
package/src/call/base.ts
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
import { Protocol, TransactionBlock, CallResponse, Guard} from 'wowok';
|
|
3
|
+
import { Protocol, TransactionBlock, CallResponse, Guard, TransactionArgument, Entity, IsValidAddress, Resource, TxbObject, TransactionResult} from 'wowok';
|
|
4
4
|
import { PassportObject, Errors, ERROR, Permission,
|
|
5
5
|
PermissionIndexType, GuardParser, Passport, WitnessFill
|
|
6
6
|
} from 'wowok';
|
|
7
7
|
import { query_permission } from '../permission';
|
|
8
8
|
import { Account } from '../account';
|
|
9
|
-
import { ObjectBase
|
|
10
|
-
|
|
9
|
+
import { ObjectBase} from '../objects';
|
|
10
|
+
import { query_entity } from '../entity';
|
|
11
11
|
|
|
12
|
+
export interface AddressMark {
|
|
13
|
+
nick_name?:string;
|
|
14
|
+
tags:string[];
|
|
15
|
+
groups:string[];
|
|
16
|
+
}
|
|
12
17
|
export interface ResponseData extends ObjectBase {
|
|
13
18
|
change:'created' | 'mutated' | string;
|
|
14
19
|
}
|
|
15
|
-
|
|
16
20
|
export interface GuardInfo_forCall {
|
|
17
21
|
guard: string[];
|
|
18
22
|
witness: WitnessFill[];
|
|
@@ -39,7 +43,7 @@ export function ResponseData(response: CallResponse | undefined ) : ResponseData
|
|
|
39
43
|
}
|
|
40
44
|
export class CallBase {
|
|
41
45
|
// operation implementation for a call
|
|
42
|
-
protected async operate(txb:TransactionBlock, passport?:PassportObject) {};
|
|
46
|
+
protected async operate(txb:TransactionBlock, passport?:PassportObject, account?:string) {};
|
|
43
47
|
constructor () {}
|
|
44
48
|
// return WitnessFill to resolve filling witness, and than 'call_with_witness' to complete the call;
|
|
45
49
|
// return ResponseData when the call has completed;
|
|
@@ -56,7 +60,7 @@ export class CallBase {
|
|
|
56
60
|
if (query) {
|
|
57
61
|
const txb = new TransactionBlock();
|
|
58
62
|
const passport = new Passport(txb, query!);
|
|
59
|
-
this.operate(new TransactionBlock(), passport?.get_object())
|
|
63
|
+
this.operate(new TransactionBlock(), passport?.get_object(), param?.account)
|
|
60
64
|
passport.destroy();
|
|
61
65
|
|
|
62
66
|
return await Protocol.Client().signAndExecuteTransaction({
|
|
@@ -103,7 +107,7 @@ export class CallBase {
|
|
|
103
107
|
if (query) {
|
|
104
108
|
const txb = new TransactionBlock();
|
|
105
109
|
const passport = new Passport(txb, query!);
|
|
106
|
-
this.operate(new TransactionBlock(), passport?.get_object())
|
|
110
|
+
this.operate(new TransactionBlock(), passport?.get_object(), account)
|
|
107
111
|
passport.destroy();
|
|
108
112
|
|
|
109
113
|
return await Protocol.Client().signAndExecuteTransaction({
|
|
@@ -124,11 +128,27 @@ export class CallBase {
|
|
|
124
128
|
if (!pair) ERROR(Errors.Fail, 'account invalid')
|
|
125
129
|
|
|
126
130
|
const txb = new TransactionBlock();
|
|
127
|
-
this.operate(txb);
|
|
131
|
+
this.operate(txb, undefined, account);
|
|
128
132
|
return await Protocol.Client().signAndExecuteTransaction({
|
|
129
133
|
transaction: txb,
|
|
130
134
|
signer: pair!,
|
|
131
135
|
options:{showObjectChanges:true},
|
|
132
136
|
});
|
|
133
137
|
}
|
|
138
|
+
|
|
139
|
+
protected mark = async (txb:TransactionBlock, object: string | TransactionResult, mark:AddressMark, account?:string) => {
|
|
140
|
+
const addr = Account.Instance().get_address(account);
|
|
141
|
+
if (addr) {
|
|
142
|
+
const r = await query_entity(addr);
|
|
143
|
+
if (r?.resource) {
|
|
144
|
+
const resource = Resource.From(txb, r.resource);
|
|
145
|
+
resource.add_tags(object, mark.nick_name??'', mark.tags);
|
|
146
|
+
if (mark.groups.length > 0) {
|
|
147
|
+
resource.add2(object, mark.groups);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
ERROR(Errors.InvalidParam, 'account - ' + account)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
134
154
|
}
|
package/src/call/demand.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { TransactionBlock,
|
|
2
|
-
import { PassportObject, IsValidAddress, Errors, ERROR, Permission,
|
|
3
|
-
PermissionIndexType, Demand,
|
|
4
|
-
} from 'wowok';
|
|
1
|
+
import { TransactionBlock, IsValidArgType, IsValidCoinType } from 'wowok';
|
|
2
|
+
import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIndex,
|
|
3
|
+
PermissionIndexType, Demand, } from 'wowok';
|
|
5
4
|
import { query_objects, ObjectDemand } from '../objects';
|
|
6
5
|
import { CallBase, CallResult } from "./base";
|
|
6
|
+
import { Account } from '../account';
|
|
7
7
|
|
|
8
8
|
export interface CallDemand_Data {
|
|
9
9
|
object?: string; // undefined for creating a new object
|
|
@@ -13,7 +13,7 @@ export interface CallDemand_Data {
|
|
|
13
13
|
guard?: {address:string; service_id_in_guard?:number};
|
|
14
14
|
description?: string;
|
|
15
15
|
time_expire?: {op: 'duration'; minutes:number} | {op:'set'; time:number};
|
|
16
|
-
bounty?: {op:'add'; object
|
|
16
|
+
bounty?: {op:'add'; object:{address:string}|{balance:string|number}} | {op:'refund'} | {op:'reward'; service:string};
|
|
17
17
|
present?: {service: string | number; recommend_words:string; service_pay_type:string, guard?:string | 'fetch'}; // guard is the present guard of Demand
|
|
18
18
|
reward?: string; // rerward the service
|
|
19
19
|
refund?: boolean;
|
|
@@ -77,7 +77,7 @@ export class CallDemand extends CallBase {
|
|
|
77
77
|
}
|
|
78
78
|
return this.exec(account);
|
|
79
79
|
}
|
|
80
|
-
protected async operate(txb:TransactionBlock, passport?:PassportObject) {
|
|
80
|
+
protected async operate(txb:TransactionBlock, passport?:PassportObject, account?:string) {
|
|
81
81
|
let obj : Demand | undefined ; let permission: any;
|
|
82
82
|
|
|
83
83
|
if (!this.data.object) {
|
|
@@ -109,16 +109,14 @@ export class CallDemand extends CallBase {
|
|
|
109
109
|
}
|
|
110
110
|
if (this.data?.bounty !== undefined) {
|
|
111
111
|
if (this.data.bounty.op === 'add') {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
deposit = txb.splitCoins(this.data.bounty.object, [b])[0];
|
|
118
|
-
}
|
|
119
|
-
if (deposit) {
|
|
120
|
-
obj?.deposit(deposit);
|
|
112
|
+
if (IsValidAddress((this.data.bounty.object as any)?.address)) {
|
|
113
|
+
obj.deposit((this.data.bounty.object as any)?.address)
|
|
114
|
+
} else if ((this.data.bounty.object as any)?.balance !== undefined){
|
|
115
|
+
if (!IsValidCoinType(this.data.type_parameter)) {
|
|
116
|
+
ERROR(Errors.IsValidCoinType, 'demand bounty')
|
|
121
117
|
}
|
|
118
|
+
const r = await Account.Instance().get_coin_object(txb, (this.data.bounty.object as any)?.balance, account, this.data.type_parameter);
|
|
119
|
+
if (r) obj.deposit(r)
|
|
122
120
|
}
|
|
123
121
|
} else if (this.data.bounty.op === 'refund') {
|
|
124
122
|
obj?.refund(passport);
|
package/src/call/guard.ts
CHANGED
|
@@ -64,7 +64,6 @@ export class CallGuard extends CallBase {
|
|
|
64
64
|
const bytes = (concatenate(Uint8Array, ...output) as Uint8Array);
|
|
65
65
|
const txb = new TransactionBlock();
|
|
66
66
|
|
|
67
|
-
console.log(bytes)
|
|
68
67
|
const obj = txb.moveCall({
|
|
69
68
|
target: Protocol.Instance().guardFn('new') as FnCallType,
|
|
70
69
|
arguments: [txb.pure.string(this.data.description), txb.pure.vector('u8', [].slice.call(bytes.reverse()))],
|
|
@@ -106,13 +105,11 @@ export class CallGuard extends CallBase {
|
|
|
106
105
|
const buildNode = (guard_node:GuardNode, type_required:ValueType | 'number' | 'variable', table:GuardConst[], output:Uint8Array[]) => {
|
|
107
106
|
const node: any = guard_node as any;
|
|
108
107
|
if (node?.identifier !== undefined) {
|
|
109
|
-
console.log(node)
|
|
110
108
|
const f = table.find(v=>v.identifier === node.identifier);
|
|
111
109
|
if (f) {
|
|
112
110
|
checkType(f.value_type, type_required, node);
|
|
113
111
|
output.push(Bcs.getInstance().ser(ValueType.TYPE_U8, ContextType.TYPE_CONSTANT));
|
|
114
112
|
output.push(Bcs.getInstance().ser(ValueType.TYPE_U8, node.identifier))
|
|
115
|
-
console.log(2)
|
|
116
113
|
} else {
|
|
117
114
|
ERROR(Errors.InvalidParam, 'node identifier - ' + node.toString());
|
|
118
115
|
}
|
package/src/call/machine.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIndex, WitnessFill,
|
|
1
|
+
import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIndex, TransactionBlock,
|
|
3
2
|
PermissionIndexType, Machine, Machine_Forward, Machine_Node, Deliverable, ParentProgress, Progress, ProgressNext,
|
|
4
3
|
} from 'wowok';
|
|
5
4
|
import { CallBase, CallResult } from "./base";
|
package/src/call/personal.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { TransactionBlock
|
|
2
|
-
import { PassportObject, IsValidAddress, Errors, ERROR, Entity, Entity_Info,
|
|
1
|
+
import { TransactionBlock } from 'wowok';
|
|
2
|
+
import { PassportObject, IsValidAddress, Errors, ERROR, Entity, Entity_Info, GroupName, Resource, WitnessFill} from 'wowok';
|
|
3
3
|
import { CallBase, CallResult } from "./base";
|
|
4
4
|
|
|
5
5
|
export interface CallPersonal_Data {
|
|
6
6
|
object?: string; // undefined for creating a new object
|
|
7
7
|
information?: Entity_Info;
|
|
8
8
|
transfer_to?: string;
|
|
9
|
-
|
|
10
|
-
| {op:'
|
|
11
|
-
| {op:'
|
|
12
|
-
| {op:'
|
|
13
|
-
| {op:'
|
|
14
|
-
|
|
9
|
+
group?: {op:'add group'; data:{group_name:string | GroupName; address:string[]}}
|
|
10
|
+
| {op:'remove group'; data:{group_name:string | GroupName; address:string[]}}
|
|
11
|
+
| {op:'clear group'; group_name:string | GroupName}
|
|
12
|
+
| {op:'add address'; data:{address:string; group_name:(string | GroupName)[]}}
|
|
13
|
+
| {op:'remove address'; data:{address:string; group_name:(string | GroupName)[]}};
|
|
14
|
+
tag?: {op:'add'; data:{address:string; nick_name:string; tags:string[]}}
|
|
15
15
|
| {op:'remove'; address:string};
|
|
16
16
|
close?: boolean; // close a personal resource
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export class
|
|
19
|
+
export class CallPersonal extends CallBase {
|
|
20
20
|
data: CallPersonal_Data;
|
|
21
21
|
constructor(data: CallPersonal_Data) {
|
|
22
22
|
super();
|
|
@@ -44,42 +44,42 @@ export class CallEntity extends CallBase {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (obj && obj?.get_object()) {
|
|
47
|
-
if (this.data?.
|
|
48
|
-
switch(this.data.
|
|
47
|
+
if (this.data?.group !== undefined) {
|
|
48
|
+
switch(this.data.group.op) {
|
|
49
49
|
case 'add address':
|
|
50
|
-
obj?.add2(this.data.
|
|
50
|
+
obj?.add2(this.data.group.data.address, this.data.group.data.group_name)
|
|
51
51
|
break;
|
|
52
|
-
case 'add
|
|
53
|
-
if (this.data.
|
|
54
|
-
const n = this.data.
|
|
55
|
-
this.data.
|
|
52
|
+
case 'add group':
|
|
53
|
+
if (this.data.group.data.group_name === GroupName.DislikeName || this.data.group.data.group_name === GroupName.LikeName) {
|
|
54
|
+
const n = this.data.group.data.group_name;
|
|
55
|
+
this.data.group.data.address.forEach(v => {if (obj) entity.mark(obj, v, n)})
|
|
56
56
|
} else {
|
|
57
|
-
obj?.add(this.data.
|
|
57
|
+
obj?.add(this.data.group.data.group_name, this.data.group.data.address)
|
|
58
58
|
}
|
|
59
59
|
break;
|
|
60
|
-
case 'clear
|
|
61
|
-
obj?.remove(this.data.
|
|
60
|
+
case 'clear group':
|
|
61
|
+
obj?.remove(this.data.group.group_name, [], true)
|
|
62
62
|
break;
|
|
63
63
|
case 'remove address':
|
|
64
|
-
obj?.remove2(this.data.
|
|
64
|
+
obj?.remove2(this.data.group.data.address, this.data.group.data.group_name)
|
|
65
65
|
break;
|
|
66
|
-
case 'remove
|
|
67
|
-
if (this.data.
|
|
68
|
-
const n = this.data.
|
|
69
|
-
this.data.
|
|
66
|
+
case 'remove group':
|
|
67
|
+
if (this.data.group.data.group_name === GroupName.DislikeName || this.data.group.data.group_name === GroupName.LikeName) {
|
|
68
|
+
const n = this.data.group.data.group_name;
|
|
69
|
+
this.data.group.data.address.forEach(v => {if (obj) entity.mark(obj, v, n)})
|
|
70
70
|
} else {
|
|
71
|
-
obj?.remove(this.data.
|
|
71
|
+
obj?.remove(this.data.group.data.group_name, this.data.group.data.address)
|
|
72
72
|
}
|
|
73
73
|
break;
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
if (this.data?.
|
|
77
|
-
switch(this.data.
|
|
76
|
+
if (this.data?.tag !== undefined) {
|
|
77
|
+
switch(this.data.tag.op) {
|
|
78
78
|
case 'add':
|
|
79
|
-
obj?.add_tags(this.data.
|
|
79
|
+
obj?.add_tags(this.data.tag.data.address, this.data.tag.data.nick_name, this.data.tag.data.tags)
|
|
80
80
|
break;
|
|
81
81
|
case 'remove':
|
|
82
|
-
obj?.remove_tags(this.data.
|
|
82
|
+
obj?.remove_tags(this.data.tag.address)
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
85
85
|
}
|
package/src/call/service.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIn
|
|
|
5
5
|
} from 'wowok';
|
|
6
6
|
import { query_objects, ObjectService } from '../objects';
|
|
7
7
|
import { CallBase, CallResult } from "./base";
|
|
8
|
+
import { Account } from '../account';
|
|
8
9
|
|
|
9
10
|
export interface CallService_Data {
|
|
10
11
|
object?: string; // undefined for creating a new object
|
|
@@ -31,7 +32,7 @@ export interface CallService_Data {
|
|
|
31
32
|
| {op:'removeall'} | {op:'remove', addresses:string[]};
|
|
32
33
|
customer_required_info?: {pubkey:string; required_info:(string | BuyRequiredEnum)[]};
|
|
33
34
|
sales?: {op:'add', sales:Service_Sale[]} | {op:'remove'; sales_name:string[]}
|
|
34
|
-
order_new?: {buy_items:Service_Buy[],
|
|
35
|
+
order_new?: {buy_items:Service_Buy[], discount?:string, machine?:string, customer_info_crypto?: Customer_RequiredInfo, guard?:string | 'fetch'}
|
|
35
36
|
order_required_info?: {order:string; info:Customer_RequiredInfo};
|
|
36
37
|
order_refund?: {order:string; guard?:string;} | {order:string; arb:string; arb_token_type:string}; // guard address
|
|
37
38
|
order_withdrawl?: {order:string; data:WithdrawPayee}; // guard address
|
|
@@ -146,7 +147,7 @@ export class CallService extends CallBase {
|
|
|
146
147
|
}
|
|
147
148
|
return this.exec(account);
|
|
148
149
|
}
|
|
149
|
-
protected async operate (txb:TransactionBlock, passport?:PassportObject) {
|
|
150
|
+
protected async operate (txb:TransactionBlock, passport?:PassportObject, account?:string) {
|
|
150
151
|
let obj : Service | undefined ; let permission: any; let payee: any;
|
|
151
152
|
|
|
152
153
|
if (!this.data.object) {
|
|
@@ -300,16 +301,12 @@ export class CallService extends CallBase {
|
|
|
300
301
|
b += BigInt(v.max_price) * BigInt(v.count)
|
|
301
302
|
})
|
|
302
303
|
if (b > BigInt(0)) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
coin
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if (coin) {
|
|
311
|
-
//@ crypto tools support
|
|
312
|
-
obj?.buy(this.data.order_new.buy_items, coin, this.data.order_new.discount, this.data.order_new.machine, this.data.order_new.customer_info_crypto, passport)
|
|
304
|
+
const coin = await Account.Instance().get_coin_object(txb, b, account, this.data.type_parameter);
|
|
305
|
+
if (coin) {
|
|
306
|
+
//@ crypto tools support
|
|
307
|
+
obj?.buy(this.data.order_new.buy_items, coin, this.data.order_new.discount,
|
|
308
|
+
this.data.order_new.machine, this.data.order_new.customer_info_crypto, passport)
|
|
309
|
+
}
|
|
313
310
|
}
|
|
314
311
|
}
|
|
315
312
|
if (this.data?.order_payer !== undefined && obj) {
|
package/src/call/treasury.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIn
|
|
|
4
4
|
} from 'wowok';
|
|
5
5
|
import { query_objects, ObjectTreasury } from '../objects';
|
|
6
6
|
import { CallBase, CallResult } from "./base";
|
|
7
|
+
import { Account } from '../account';
|
|
7
8
|
|
|
8
9
|
export interface CallTreasury_Data {
|
|
9
10
|
object?: string; // undefined for creating a new object
|
|
@@ -14,7 +15,7 @@ export interface CallTreasury_Data {
|
|
|
14
15
|
withdraw_mode?: Treasury_WithdrawMode;
|
|
15
16
|
withdraw_guard?: {op:'add' | 'set'; data:{guard:string, amount:string}[]} | {op:'remove', guards:string[]} | {op:'removeall'};
|
|
16
17
|
deposit_guard?: string;
|
|
17
|
-
deposit?: {data:
|
|
18
|
+
deposit?: {data:{balance:string|number; index?:number; remark?:string; for_object?:string; for_guard?:string}; guard?:string | 'fetch'};
|
|
18
19
|
receive?: {payment:string; received_object:string};
|
|
19
20
|
withdraw?:WithdrawParam;
|
|
20
21
|
}
|
|
@@ -102,7 +103,7 @@ export class CallTreasury extends CallBase {
|
|
|
102
103
|
}
|
|
103
104
|
return this.exec(account);
|
|
104
105
|
}
|
|
105
|
-
protected async operate (txb:TransactionBlock, passport?:PassportObject) {
|
|
106
|
+
protected async operate (txb:TransactionBlock, passport?:PassportObject, account?:string) {
|
|
106
107
|
let obj : Treasury | undefined ; let permission: any;
|
|
107
108
|
if (!this.data.object) {
|
|
108
109
|
if (!this.data?.permission || !IsValidAddress(this.data?.permission)) {
|
|
@@ -149,7 +150,14 @@ export class CallTreasury extends CallBase {
|
|
|
149
150
|
obj?.receive(this.data.receive.payment, this.data.receive.received_object, passport);
|
|
150
151
|
}
|
|
151
152
|
if (this.data.deposit !== undefined) {
|
|
152
|
-
|
|
153
|
+
const coin = await Account.Instance().get_coin_object(txb, this.data.deposit.data.balance, account, this.data.type_parameter);
|
|
154
|
+
if (coin) {
|
|
155
|
+
const index = this.data.deposit.data?.index ?? 0;
|
|
156
|
+
obj?.deposit({coin:coin, index:BigInt(index), remark:this.data.deposit.data.remark ??'',
|
|
157
|
+
for_guard:this.data.deposit.data?.for_guard,
|
|
158
|
+
for_object: this.data.deposit.data?.for_object
|
|
159
|
+
})
|
|
160
|
+
}
|
|
153
161
|
}
|
|
154
162
|
if (this.data?.permission_new !== undefined) {
|
|
155
163
|
obj?.change_permission(this.data.permission_new);
|
package/src/entity.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Bcs, Entity, Entity_Info, ERROR, Errors, IsValidAddress, Protocol, TransactionBlock } from "wowok";
|
|
2
|
+
import { CacheName, PERSONAL_RESOURCE_KEY, WowokCache, CachedData} from "./cache";
|
|
3
|
+
|
|
4
|
+
export interface EntityAnswer {
|
|
5
|
+
info?: Entity_Info;
|
|
6
|
+
resource?: string;
|
|
7
|
+
like?: number;
|
|
8
|
+
dislike?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const query_entity_json = async (person_address:string) : Promise<string> => {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.stringify({data:await query_entity(person_address)});
|
|
14
|
+
} catch (e) {
|
|
15
|
+
return JSON.stringify({error:e?.toString()})
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const query_entity = async (personal_address:string) : Promise<EntityAnswer | undefined> => {
|
|
20
|
+
if (!IsValidAddress(personal_address)) {
|
|
21
|
+
ERROR(Errors.InvalidParam, 'personal_address - '+personal_address)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const cache = WowokCache.Instance().get(CacheName.resource);
|
|
25
|
+
|
|
26
|
+
if (cache) {
|
|
27
|
+
const now = new Date().getTime();
|
|
28
|
+
const data = cache.load(PERSONAL_RESOURCE_KEY(personal_address));
|
|
29
|
+
if (data) {
|
|
30
|
+
const r:CachedData = JSON.parse(data);
|
|
31
|
+
if (r.expire !== 'INFINITE' && r.expire >= now) { //update , INFINITE not supported
|
|
32
|
+
return JSON.parse(r.data) as EntityAnswer
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const e = await entity(personal_address);
|
|
38
|
+
if (e) {
|
|
39
|
+
if (cache) { // save
|
|
40
|
+
const r:CachedData = {expire:new Date().getTime(), data:JSON.stringify(e)}
|
|
41
|
+
cache.save(PERSONAL_RESOURCE_KEY(personal_address), JSON.stringify(r));
|
|
42
|
+
}
|
|
43
|
+
return e
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const entity = async (personal_address:string) : Promise<EntityAnswer | undefined> => {
|
|
48
|
+
const txb = new TransactionBlock();
|
|
49
|
+
Entity.From(txb).query_ent(personal_address);
|
|
50
|
+
|
|
51
|
+
const res = await Protocol.Client().devInspectTransactionBlock({sender:personal_address, transactionBlock:txb});
|
|
52
|
+
if (res.results?.length === 1 && res.results[0].returnValues?.length === 1 ) {
|
|
53
|
+
const r = Bcs.getInstance().de_ent(Uint8Array.from(res.results[0].returnValues[0][0]));
|
|
54
|
+
const info = Bcs.getInstance().de_entInfo(Uint8Array.from(r?.avatar));
|
|
55
|
+
const d : EntityAnswer = {resource:r?.resource?.some, like:r?.like, dislike:r?.dislike, info: {
|
|
56
|
+
avatar:info.avatar, name:info.name, twitter:info.twitter, discord:info.discord, homepage:info.homepage, description:info.description
|
|
57
|
+
}};
|
|
58
|
+
return d;
|
|
59
|
+
}
|
|
60
|
+
}
|
package/src/index.ts
CHANGED
package/src/objects.ts
CHANGED
|
@@ -5,20 +5,21 @@
|
|
|
5
5
|
|
|
6
6
|
import { Protocol, Machine_Node, Machine, Treasury_WithdrawMode, Treasury_Operation,
|
|
7
7
|
Repository_Type, Repository_Policy_Mode, Repository_Policy, Service_Discount_Type, Service_Sale,
|
|
8
|
-
Progress, History, ERROR, Errors, IsValidAddress, Bcs,
|
|
8
|
+
Progress, History, ERROR, Errors, IsValidAddress, Bcs,
|
|
9
|
+
Entity_Info,
|
|
9
10
|
} from 'wowok';
|
|
10
|
-
import {WowokCache, OBJECT_KEY} from './cache'
|
|
11
|
+
import {WowokCache, OBJECT_KEY, CacheExpire, CacheName, CachedData} from './cache'
|
|
11
12
|
|
|
12
13
|
export interface ObjectBase {
|
|
13
14
|
object: string;
|
|
14
15
|
type?: string | 'Demand' | 'Progress' | 'Service' | 'Machine' | 'Order' | 'Treasury' | 'Arbitration' | 'Arb' | 'Payment' | 'Guard' |
|
|
15
|
-
'Entity' | 'Permission' | '
|
|
16
|
+
'Entity' | 'Permission' | 'Mark' | 'Repository' | 'TableItem_ProgressHistory' | 'TableItem_PermissionEntity' |
|
|
16
17
|
'TableItem_DemandPresenter' | 'TableItem_MachineNode' | 'TableItem_ServiceSale' | 'TableItem_TreasuryHistory' | 'TableItem_ArbVote' |
|
|
17
|
-
'TableItem_RepositoryData' | '
|
|
18
|
+
'TableItem_RepositoryData' | 'TableItem_MarkGroup';
|
|
18
19
|
type_raw?: string;
|
|
19
20
|
owner?: any;
|
|
20
21
|
version?: string;
|
|
21
|
-
cache_expire?:
|
|
22
|
+
cache_expire?: CacheExpire;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export interface ObjectPermission extends ObjectBase {
|
|
@@ -220,31 +221,24 @@ export interface ObjectEntity extends ObjectBase {
|
|
|
220
221
|
address: string;
|
|
221
222
|
like: number;
|
|
222
223
|
dislike: number;
|
|
223
|
-
|
|
224
|
-
name?: string;
|
|
225
|
-
description?: string;
|
|
226
|
-
avatar?: string;
|
|
227
|
-
x?: string;
|
|
228
|
-
discord?: string;
|
|
229
|
-
|
|
230
|
-
homepage?: string;
|
|
224
|
+
info: Entity_Info;
|
|
231
225
|
resource_object?: string | null;
|
|
232
226
|
lastActive_digest?: string;
|
|
233
227
|
}
|
|
234
228
|
|
|
235
|
-
export interface
|
|
229
|
+
export interface ObjectMark_Tag {
|
|
236
230
|
object: string;
|
|
237
231
|
nick_name: string;
|
|
238
232
|
tags: string[];
|
|
239
233
|
}
|
|
240
234
|
|
|
241
|
-
export interface
|
|
242
|
-
|
|
243
|
-
tags:
|
|
235
|
+
export interface ObjectMark extends ObjectBase {
|
|
236
|
+
group_count: number;
|
|
237
|
+
tags: ObjectMark_Tag[];
|
|
244
238
|
}
|
|
245
239
|
|
|
246
|
-
export interface
|
|
247
|
-
|
|
240
|
+
export interface TableItem_MarkGroup extends ObjectBase {
|
|
241
|
+
group_name: string;
|
|
248
242
|
objects: string[];
|
|
249
243
|
}
|
|
250
244
|
|
|
@@ -287,11 +281,6 @@ interface TableItemQuery {
|
|
|
287
281
|
key: {type:string, value:unknown};
|
|
288
282
|
}
|
|
289
283
|
|
|
290
|
-
export interface CachedData {
|
|
291
|
-
expire: number | 'INFINITE';
|
|
292
|
-
data: string | any;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
284
|
/* json: ObjectsQuery string */
|
|
296
285
|
export const query_objects_json = async (json:string) : Promise<string> => {
|
|
297
286
|
try {
|
|
@@ -314,8 +303,8 @@ export const query_table_json = async (json:string) : Promise<string> => {
|
|
|
314
303
|
|
|
315
304
|
export const query_objects = async (query: ObjectsQuery) : Promise<ObjectsAnswer> => {
|
|
316
305
|
var ret:ObjectBase[] = []; const pending : string[] = [];
|
|
317
|
-
|
|
318
|
-
const cache = WowokCache.Instance().get();
|
|
306
|
+
const time = new Date().getTime();
|
|
307
|
+
const cache = WowokCache.Instance().get(CacheName.object);
|
|
319
308
|
if (cache) {
|
|
320
309
|
for (let i = 0; i < query.objects.length; ++i) {
|
|
321
310
|
try {
|
|
@@ -342,10 +331,10 @@ export const query_objects = async (query: ObjectsQuery) : Promise<ObjectsAnswer
|
|
|
342
331
|
if (pending.length > 0) {
|
|
343
332
|
const res = await Protocol.Client().multiGetObjects({ids:[...pending],
|
|
344
333
|
options:{showContent:query.showContent, showType:query.showType, showOwner:query.showOwner}});
|
|
345
|
-
const
|
|
346
|
-
const cache = WowokCache.Instance().get();
|
|
334
|
+
const cache = WowokCache.Instance().get(CacheName.object);
|
|
347
335
|
|
|
348
336
|
if (cache) {
|
|
337
|
+
const now = new Date().getTime();
|
|
349
338
|
res.forEach((i) => { // save
|
|
350
339
|
try {
|
|
351
340
|
if (i?.data) {
|
|
@@ -363,7 +352,7 @@ export const query_objects = async (query: ObjectsQuery) : Promise<ObjectsAnswer
|
|
|
363
352
|
return {objects:ret}
|
|
364
353
|
}
|
|
365
354
|
|
|
366
|
-
export const
|
|
355
|
+
export const queryTableItem_Personal = async (address:string) : Promise<ObjectEntity> => {
|
|
367
356
|
if (!IsValidAddress(address)) ERROR(Errors.IsValidAddress, 'entity.address')
|
|
368
357
|
const res = await Protocol.Client().getDynamicFieldObject({parentId:Protocol.Instance().objectEntity(), name:{type:'address', value:address}});
|
|
369
358
|
return data2object(res?.data) as ObjectEntity
|
|
@@ -405,7 +394,7 @@ export const tableItemQuery_RepositoryData = async (repository_object:string | O
|
|
|
405
394
|
}
|
|
406
395
|
return await tableItem({parent:repository_object, key:{type:Protocol.Instance().package('wowok')+'::repository::DataKey', value:{id:address, key:name}}})
|
|
407
396
|
}
|
|
408
|
-
export const
|
|
397
|
+
export const tableItemQuery_ResourceGroup = async (resource_object:string | ObjectMark, name:string) : Promise<ObjectBase> => {
|
|
409
398
|
return await tableItem(tableItemQuery_byString(resource_object, name))
|
|
410
399
|
}
|
|
411
400
|
|
|
@@ -415,7 +404,7 @@ function tableItemQuery_byAddress(parent:string | ObjectDemand | ObjectPermissio
|
|
|
415
404
|
}
|
|
416
405
|
return {parent:parent, key:{type:'address', value:address}};
|
|
417
406
|
}
|
|
418
|
-
function tableItemQuery_byString(parent:string | ObjectMachine | ObjectService |
|
|
407
|
+
function tableItemQuery_byString(parent:string | ObjectMachine | ObjectService | ObjectMark, name:string) : TableItemQuery {
|
|
419
408
|
if (typeof(parent) !== 'string') {
|
|
420
409
|
parent = parent.object;
|
|
421
410
|
}
|
|
@@ -581,11 +570,11 @@ export function data2object(data?:any) : ObjectBase {
|
|
|
581
570
|
case 'Resource' :
|
|
582
571
|
return {
|
|
583
572
|
object:id, type:type, type_raw:type_raw, owner:owner, version:version,
|
|
584
|
-
|
|
573
|
+
group_count:parseInt(content?.marks?.fields?.size),
|
|
585
574
|
tags:content?.tags?.map((v:any) => {
|
|
586
575
|
return {object:v?.fields?.object, nick_name:v?.fields?.nick, tags:v?.fields?.tags}
|
|
587
576
|
})
|
|
588
|
-
} as
|
|
577
|
+
} as ObjectMark;
|
|
589
578
|
}
|
|
590
579
|
}
|
|
591
580
|
|
|
@@ -644,15 +633,15 @@ export function data2object(data?:any) : ObjectBase {
|
|
|
644
633
|
return {
|
|
645
634
|
object:id, type:'Entity', type_raw:type_raw, owner:owner, version:version,
|
|
646
635
|
address:content?.name, like:content?.value?.fields?.like, dislike:content?.value?.fields?.dislike,
|
|
647
|
-
resource_object: content?.value?.fields?.resource, lastActive_digest: data?.previousTransaction,
|
|
648
|
-
homepage:info?.homepage, name:info?.name, avatar:info?.avatar,
|
|
649
|
-
description:info?.description
|
|
636
|
+
resource_object: content?.value?.fields?.resource, lastActive_digest: data?.previousTransaction,
|
|
637
|
+
info : {homepage:info?.homepage, name:info?.name, avatar:info?.avatar, twitter:info?.twitter, discord:info?.discord,
|
|
638
|
+
description:info?.description}
|
|
650
639
|
} as ObjectEntity;
|
|
651
640
|
} else if (end.includes('::resource::Addresses>')) {
|
|
652
641
|
return {
|
|
653
642
|
object:id, type:'Entity', type_raw:type_raw, owner:owner, version:version,
|
|
654
|
-
|
|
655
|
-
} as
|
|
643
|
+
group_name:content?.name, objects:content?.value?.fields?.addresses
|
|
644
|
+
} as TableItem_MarkGroup;
|
|
656
645
|
}
|
|
657
646
|
}
|
|
658
647
|
}
|
package/src/permission.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { TransactionBlock, } from 'wowok';
|
|
7
|
-
import { Protocol, Bcs, IsValidAddress, Errors, ERROR, Permission,
|
|
7
|
+
import { Protocol, Bcs, IsValidAddress, Errors, ERROR, Permission, PermissionAnswer, BCS} from 'wowok';
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
export interface PermissionQuery {
|