UNPKG

wowok

Version:

Create, collaborate, and transact on your own terms with the AI-driven web3 collaboration protocol.

559 lines (516 loc) 24.7 kB
import { Protocol, FnCallType, ValueType, RepositoryValueType, RepositoryAddress, PermissionObject, PassportObject, TxbObject, } from './protocol'; import { PermissionIndexType, Permission } from './permission' import { Bcs, array_unique, IsValidDesription, IsValidAddress, IsValidArray, IsValidName, ValueTypeConvert} from './utils'; import { ERROR, Errors } from './exception'; import { MAX_U8, MAX_U128, MAX_U256, MAX_U64, parseObjectType } from './utils'; import { type TransactionResult, Transaction as TransactionBlock } from '@mysten/sui/transactions'; export enum Repository_Policy_Mode { POLICY_MODE_FREE = 0, POLICY_MODE_STRICT = 1, } export enum Repository_Type { NORMAL = 0, WOWOK_GRANTEE = 1, WOWOK_ORACLE = 2 } export interface RepData { id: string; name: string; dataType: RepositoryValueType; data: string | string[]; object: string; } export interface Repository_Policy { key:string; description: string; dataType: RepositoryValueType; permissionIndex?: PermissionIndexType | null; // PermissionIndex like, must be geater than 1000 } export interface Repository_Policy_Data { key: string; data: Repository_Value[]; value_type?: ValueType; // Specifies a data type prefix; If the data prefix is already included in the data byte stream, there is no need to specify it. } export interface Repository_Value { address: string; // UID: address or objectid bcsBytes: Uint8Array; // BCS contents. Notice that: First Byte be the Type by caller, or specify type with 'Repository_Policy_Data.value_type' field. } export interface Repository_Value2 { key: string; bcsBytes: Uint8Array; } export interface Repository_Policy_Data2 { address: string; data: Repository_Value2[]; value_type?: ValueType; } export interface Repository_Policy_Data_Remove { key: string; address: string; } export class Repository { protected permission ; protected object:TxbObject; protected txb; get_object() { return this.object } private constructor(txb:TransactionBlock, permission:PermissionObject) { this.txb = txb; this.permission = permission; this.object = ''; } static From(txb:TransactionBlock, permission:PermissionObject, object:TxbObject) : Repository { let r = new Repository(txb, permission); r.object = Protocol.TXB_OBJECT(txb, object); return r } static New(txb:TransactionBlock, permission:PermissionObject, description:string, policy_mode: Repository_Policy_Mode=Repository_Policy_Mode.POLICY_MODE_FREE, passport?:PassportObject) : Repository { if (!Protocol.IsValidObjects([permission])) { ERROR(Errors.IsValidObjects, 'permission') } if (!IsValidDesription(description)) { ERROR(Errors.IsValidDesription) } let r = new Repository(txb, permission); if (passport) { r.object = txb.moveCall({ target:Protocol.Instance().repositoryFn('new_with_passport') as FnCallType, arguments:[passport, txb.pure.string(description), txb.pure.u8(policy_mode), Protocol.TXB_OBJECT(txb, permission)], }) } else { r.object = txb.moveCall({ target:Protocol.Instance().repositoryFn('new') as FnCallType, arguments:[txb.pure.string(description), txb.pure.u8(policy_mode), Protocol.TXB_OBJECT(txb, permission)], }) } return r } launch() : RepositoryAddress { return this.txb.moveCall({ target:Protocol.Instance().repositoryFn('create') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object)], }) } add_data(data:Repository_Policy_Data) { if (!Repository.IsValidName(data.key)) { ERROR(Errors.IsValidName, 'add_data') } let bValid = true; data.data.forEach((value) => { if (!IsValidAddress(value.address)) bValid = false; if (!Repository.IsValidValue(value.bcsBytes)) bValid = false; }); if (!bValid) { ERROR(Errors.InvalidParam, 'add_data') } if (data?.value_type !== undefined) { data.data.forEach((d) => this.txb.moveCall({ target:Protocol.Instance().repositoryFn('add') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.address(d.address), this.txb.pure.string(data.key), this.txb.pure.u8(data.value_type!), this.txb.pure.vector('u8', [...d.bcsBytes]), Protocol.TXB_OBJECT(this.txb, this.permission), ], })) } else { data.data.forEach((d) => this.txb.moveCall({ target:Protocol.Instance().repositoryFn('add_typed_data') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.address(d.address), this.txb.pure.string(data.key), this.txb.pure.vector('u8', [...d.bcsBytes]), Protocol.TXB_OBJECT(this.txb, this.permission), ], })) } } add_data2(data:Repository_Policy_Data2) { if (!IsValidAddress(data.address)) { ERROR(Errors.IsValidAddress, 'add_data2') } let bValid = true; data.data.forEach((value) => { if (!Repository.IsValidName(value.key)) bValid = false; if (!Repository.IsValidValue(value.bcsBytes)) bValid = false; }); if (!bValid) { ERROR(Errors.InvalidParam, 'add_data2') } if (data?.value_type !== undefined) { data.data.forEach((d) => this.txb.moveCall({ target:Protocol.Instance().repositoryFn('add') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.address(data.address), this.txb.pure.string(d.key), this.txb.pure.u8(data.value_type!), this.txb.pure.vector('u8', [...d.bcsBytes]), Protocol.TXB_OBJECT(this.txb, this.permission), ], })) } else { data.data.forEach((d) => this.txb.moveCall({ target:Protocol.Instance().repositoryFn('add_typed_data') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.address(data.address), this.txb.pure.string(d.key), this.txb.pure.vector('u8', [...d.bcsBytes]), Protocol.TXB_OBJECT(this.txb, this.permission), ], })) } } remove(address:string, key:string) { if (!Repository.IsValidName(key)) { ERROR(Errors.IsValidName) } if (!IsValidAddress(address)) { ERROR(Errors.IsValidAddress) } this.txb.moveCall({ target:Protocol.Instance().repositoryFn('remove') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.address(address), this.txb.pure.string(key), Protocol.TXB_OBJECT(this.txb, this.permission), ], }) } add_reference(references:string[], passport?:PassportObject) { if (references.length === 0) return; if (!IsValidArray(references, IsValidAddress)) { ERROR(Errors.IsValidArray, 'add_reference') } if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('reference_add_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.vector('address', array_unique(references)), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('reference_add') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.vector('address', array_unique(references)), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } remove_reference(references:string[], removeall?:boolean, passport?:PassportObject) { if (references.length === 0 && !removeall) return if (!IsValidArray(references, IsValidAddress)) { ERROR(Errors.IsValidArray, 'remove_reference') } if (removeall) { if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('reference_removeall_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('reference_removeall') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } else { if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('reference_remove_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.vector('address', array_unique(references)), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('reference_remove') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.vector('address', array_unique(references)), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } } // add or modify the old add_policies(policies:Repository_Policy[], passport?:PassportObject) { if (policies.length === 0) return; let bValid = true; policies.forEach((p) => { if (!IsValidDesription(p.description) || !Repository.IsValidName(p.key)) { bValid = false } }); if (!bValid) { ERROR(Errors.InvalidParam, 'policies') } policies.forEach((policy) => { let permission_index = this.txb.pure.option('u64', policy?.permissionIndex ? policy?.permissionIndex : undefined); if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_add_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(policy.key), this.txb.pure.string(policy.description), permission_index, this.txb.pure.u8(policy.dataType), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_add') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(policy.key), this.txb.pure.string(policy.description), permission_index, this.txb.pure.u8(policy.dataType), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } }); } remove_policies(policy_keys:string[], removeall?:boolean, passport?:PassportObject) { if (policy_keys.length === 0) return ; if (!IsValidArray(policy_keys, Repository.IsValidName)){ ERROR(Errors.InvalidParam, 'policy_keys') } if (passport) { if (removeall) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_removeall_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_remove_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.vector('string', array_unique(policy_keys)), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } else { if (removeall) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_removeall') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_remove') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.vector('string', array_unique(policy_keys)), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } } rename_policy(policy_key:string, new_policy_key:string, passport?:PassportObject) { if (!IsValidName(policy_key) || !IsValidName(new_policy_key)) { ERROR(Errors.IsValidName, 'change_policy') } if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_rename_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(policy_key), this.txb.pure.string(new_policy_key), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_rename') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(policy_key), this.txb.pure.string(new_policy_key), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } // PermissionIndex.description_set set_description(description:string, passport?:PassportObject) { if (!IsValidDesription(description)){ ERROR(Errors.IsValidDesription) } if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('description_set_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(description), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('description_set') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(description), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } set_policy_mode(policy_mode:Repository_Policy_Mode, passport?:PassportObject) { if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('mode_set_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.u8(policy_mode), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('mode_set') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.u8(policy_mode), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } set_policy_description(policy:string, description:string, passport?:PassportObject) { if (!Repository.IsValidName(policy)) { ERROR(Errors.IsValidName, 'policy') } if (!IsValidDesription(description)) { ERROR(Errors.IsValidDesription) } if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_description_set_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(policy), this.txb.pure.string(description), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_description_set') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), this.txb.pure.string(policy), this.txb.pure.string(description), Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } set_policy_permission(policy:string, permission_index?:number, passport?:PassportObject) { if (!Repository.IsValidName(policy)) { ERROR(Errors.IsValidName, 'policy') } let index = this.txb.pure.option('u64', undefined); if (permission_index !== undefined) { if(!Permission.IsValidPermissionIndex(permission_index)) { ERROR(Errors.IsValidPermissionIndex) } index = this.txb.pure.option('u64', permission_index); } if (passport) { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_permission_set_with_passport') as FnCallType, arguments:[passport, Protocol.TXB_OBJECT(this.txb, this.object), index, Protocol.TXB_OBJECT(this.txb, this.permission)] }) } else { this.txb.moveCall({ target:Protocol.Instance().repositoryFn('policy_permission_set') as FnCallType, arguments:[Protocol.TXB_OBJECT(this.txb, this.object), index, Protocol.TXB_OBJECT(this.txb, this.permission)] }) } } change_permission(new_permission:PermissionObject) { if (!Protocol.IsValidObjects([new_permission])) { ERROR(Errors.IsValidObjects) } this.txb.moveCall({ target:Protocol.Instance().repositoryFn('permission_set') as FnCallType, arguments: [Protocol.TXB_OBJECT(this.txb, this.object), Protocol.TXB_OBJECT(this.txb, this.permission), Protocol.TXB_OBJECT(this.txb, new_permission)], typeArguments:[] }) this.permission = new_permission } static MAX_POLICY_COUNT = 120; static MAX_KEY_LENGTH = 128; static MAX_VALUE_LENGTH = 204800; static MAX_REFERENCE_COUNT = 100; static IsValidName = (key:string) => { return key.length <= Repository.MAX_KEY_LENGTH && key.length != 0; } static IsValidValue = (value:Uint8Array) => { return value.length < Repository.MAX_VALUE_LENGTH; } static rpc_de_data(fields:any) : RepData [] { const rep: RepData[] = fields?.map((v:any) => { const value = new Uint8Array((v?.data?.content?.fields as any)?.value); const type = value?.length > 0 ? value[0] as ValueType : null; var d : any = value.length > 0 ? value.slice(1) : Uint8Array.from([]); if (type === ValueType.TYPE_STRING) { d = Bcs.getInstance().de(ValueType.TYPE_VEC_U8, d); d = new TextDecoder().decode(Uint8Array.from(d)); } else if (type === ValueType.TYPE_VEC_STRING) { d = Bcs.getInstance().de(ValueType.TYPE_VEC_VEC_U8, d) as []; d = d.map((i:any) => { return new TextDecoder().decode(Uint8Array.from(i)); }) } else { d = Bcs.getInstance().de(value[0], d); if (type === ValueType.TYPE_ADDRESS) { d = '0x' + d; } else if (type === ValueType.TYPE_VEC_ADDRESS) { d = d.map((v:string) => { return ('0x' + v) } ); } else if (type === ValueType.TYPE_BOOL) { d = d ? 'True' : 'False' } }; return {object:v?.data?.content?.fields?.id?.id, id:(v?.data?.content?.fields as any)?.name?.fields?.id, name:(v?.data?.content?.fields as any)?.name?.fields?.key, data:d, dataType: ValueTypeConvert(type) } }); return rep; } static DataType2ValueType(data:string) : ValueType | undefined{ try { const value = BigInt(data); var t = ValueType.TYPE_U8; if (value <= MAX_U8) { } else if (value <= MAX_U64) { t = ValueType.TYPE_U64; } else if (value <= MAX_U128) { t = ValueType.TYPE_U128; } else if (value <= MAX_U256) { t = ValueType.TYPE_U256; } else { return undefined } } catch (e) { console.log(e) } return undefined } static ResolveRepositoryData = (dataType:RepositoryValueType, data:string | boolean | string[]) : {type:ValueType, data: Uint8Array} | undefined => { if (dataType === RepositoryValueType.String) { return {type: ValueType.TYPE_STRING, data: Bcs.getInstance().ser(ValueType.TYPE_VEC_U8, new TextEncoder().encode(data.toString()))} } else if (dataType === RepositoryValueType.PositiveNumber) { const t = Repository.DataType2ValueType(data as string); if (!t) return undefined; return {type:t, data:Bcs.getInstance().ser(t, data)} } else if (dataType === RepositoryValueType.Address) { if (!IsValidAddress(data as string)) return undefined; return {type:ValueType.TYPE_ADDRESS, data:Bcs.getInstance().ser(ValueType.TYPE_ADDRESS, data)} } else if (dataType === RepositoryValueType.Address_Vec) { for(let i = 0; i < (data as string[]).length; ++i) { if (!IsValidAddress((data as string[])[i])) return undefined; } return {type:ValueType.TYPE_VEC_ADDRESS, data:Bcs.getInstance().ser(ValueType.TYPE_VEC_ADDRESS, data)} } else if (dataType === RepositoryValueType.PositiveNumber_Vec) { let type = ValueType.TYPE_U8; for(let i = 0; i < (data as string[]).length; ++i) { const t = Repository.DataType2ValueType(data as string); if (!t) return undefined; if (t > type) type = t; } if (type === ValueType.TYPE_U8) { type = ValueType.TYPE_VEC_U8; } else if (type === ValueType.TYPE_U64) { type = ValueType.TYPE_VEC_U64; } else if (type === ValueType.TYPE_U128) { type = ValueType.TYPE_VEC_U128; } else { type = ValueType.TYPE_VEC_U256; } return {type:type, data:Bcs.getInstance().ser(type, data)} } else if (dataType === RepositoryValueType.String_Vec) { const r = (data as string[]).map((v:string) => { return new TextEncoder().encode(v); }) return {type: ValueType.TYPE_VEC_STRING, data: Bcs.getInstance().ser(ValueType.TYPE_VEC_VEC_U8, r)} } else if (dataType === RepositoryValueType.Bool) { if (typeof(data) !== 'boolean') return undefined; return {type:ValueType.TYPE_BOOL, data:Bcs.getInstance().ser(ValueType.TYPE_BOOL, data)} } return undefined } }