wowok_agent
Version:
Create, collaborate, and transact on your own terms with the AI-driven web3 collaboration protocol.
243 lines (229 loc) • 13.1 kB
text/typescript
import { PassportObject, IsValidAddress, Errors, ERROR, Permission, PermissionIndex, TransactionBlock, TxbAddress,
PermissionIndexType, Machine, Machine_Forward, Machine_Node, Deliverable, ParentProgress, Progress, ProgressNext,
ProgressObject,
} from 'wowok';
import { CallBase, CallResult, Namedbject } from "./base";
import { Account } from '../account';
/// The execution priority is determined by the order in which the object attributes are arranged
export interface CallMachine_Data {
object?: {address:string} | {namedNew?: Namedbject}; // undefined or {named_new...} for creating a new object
permission?: {address:string} | {namedNew?: Namedbject, description?:string};
description?: string;
endpoint?: string;
consensus_repository?: {op:'set' | 'add' | 'remove' ; repositories:string[]} | {op:'removeall'};
nodes?: {op: 'add'; data: Machine_Node[]} | {op: 'remove'; names: string[], bTransferMyself?:boolean}
| {op:'rename node'; data:{old:string; new:string}[]} | {op:'add from myself'; addresses: string[]}
| {op:'remove pair'; pairs: {prior_node_name:string; node_name:string}[]}
| {op:'add forward'; data: {prior_node_name:string; node_name:string; forward:Machine_Forward; threshold?:number; remove_forward?:string}[]}
| {op:'remove forward'; data:{prior_node_name:string; node_name:string; forward_name:string}[]}
bPublished?: boolean;
progress_new?: {task_address?:string; namedNew?: Namedbject};
progress_context_repository?: {progress?:string; repository?:string};
progress_namedOperator?: {progress?:string; data:{name:string, operators:string[]}[]};
progress_parent?: {progress?:string, parent?:ParentProgress};
progress_task?: {progress?:string; task:string};
progress_hold?: {progress?:string; operation:ProgressNext; bHold:boolean; adminUnhold?:boolean};
progress_next?: {progress:string; operation:ProgressNext; deliverable:Deliverable; guard?:string | 'fetch'};
bPaused?: boolean;
clone_new?: {namedNew?: Namedbject/*, description?:string*/};
}
export class CallMachine extends CallBase { //@ todo self-owned node operate
data: CallMachine_Data;
constructor(data:CallMachine_Data) {
super();
this.data = data;
}
async call(account?:string) : Promise<CallResult> {
var checkOwner = false; const guards : string[] = [];
const perms : PermissionIndexType[] = [];
const permission_address = (this.data?.permission as any)?.address;
const object_address = (this.data?.object as any)?.address;
if (permission_address && IsValidAddress(permission_address)) {
if (!this.data?.object) {
perms.push(PermissionIndex.machine)
}
if (this.data?.description !== undefined && object_address) {
perms.push(PermissionIndex.machine_description)
}
if (this.data?.endpoint !== undefined && object_address) {
perms.push(PermissionIndex.machine_endpoint)
}
if (this.data?.consensus_repository !== undefined) {
perms.push(PermissionIndex.machine_repository)
}
if (this.data?.nodes !== undefined) {
perms.push(PermissionIndex.machine_node)
}
if (this.data?.bPublished) { // publish is an irreversible one-time operation
perms.push(PermissionIndex.machine_publish)
}
if (this.data?.progress_new !== undefined) {
perms.push(PermissionIndex.progress)
}
if (this.data?.progress_context_repository !== undefined) {
perms.push(PermissionIndex.progress_context_repository)
}
if (this.data?.progress_namedOperator !== undefined) {
perms.push(PermissionIndex.progress_namedOperator)
}
if (this.data?.progress_parent !== undefined) {
perms.push(PermissionIndex.progress_parent)
}
if (this.data?.progress_task !== undefined) {
perms.push(PermissionIndex.progress_bind_task)
}
if (this.data?.progress_hold !== undefined) {
if (this.data.progress_hold.adminUnhold) {
perms.push(PermissionIndex.progress_unhold)
}
}
if (this.data?.bPaused !== undefined) {
perms.push(PermissionIndex.machine_pause)
}
if (this.data?.progress_next?.guard !== undefined) {
if (IsValidAddress(this.data?.progress_next?.guard)) {
guards.push(this.data?.progress_next?.guard)
} else if (this.data?.object && IsValidAddress(object_address)) { // fetch guard
const guard = await Progress.QueryForwardGuard(this.data?.progress_next.progress, object_address,
await Account.Instance().get_address() ?? '0xe386bb9e01b3528b75f3751ad8a1e418b207ad979fea364087deef5250a73d3f',
this.data.progress_next.operation.next_node_name, this.data.progress_next.operation.forward);
if (guard) {
guards.push(guard)
}
}
}
return await this.check_permission_and_call(permission_address, perms, guards, checkOwner, undefined, account)
}
return await this.exec(account);
}
protected async operate(txb:TransactionBlock, passport?:PassportObject, account?:string) {
let obj : Machine | undefined ; let permission: any;
const permission_address = (this.data?.permission as any)?.address;
const object_address = (this.data?.object as any)?.address;
if (!object_address) {
if (!permission_address || !IsValidAddress(permission_address)) {
const d = (this.data?.permission as any)?.description ?? '';
permission = Permission.New(txb, d);
}
obj = Machine.New(txb, permission ? permission.get_object() : permission_address, this.data?.description??'', this.data?.endpoint ?? '', permission?undefined:passport);
} else {
if (IsValidAddress(object_address) &&permission_address && IsValidAddress(permission_address)) {
obj = Machine.From(txb, permission_address, object_address)
} else {
ERROR(Errors.InvalidParam, 'object or permission address invalid.')
}
}
if (obj) {
const perm = permission ? permission.get_object() : permission_address;
const pst = permission?undefined:passport;
if (this.data?.description !== undefined && object_address) {
obj?.set_description(this.data.description, pst);
}
if (this.data?.endpoint !== undefined && object_address) {
obj?.set_endpoint(this.data.endpoint, pst)
}
if (this.data?.consensus_repository !== undefined) {
switch (this.data.consensus_repository.op) {
case 'add':
this.data.consensus_repository.repositories.forEach(v=>obj?.add_repository(v, pst)) ;
break;
case 'remove':
obj?.remove_repository(this.data.consensus_repository.repositories, false, pst);
break;
case 'removeall':
obj?.remove_repository([], true, pst);
break;
case 'set':
obj?.remove_repository([], true, pst);
this.data.consensus_repository.repositories.forEach(v=>obj?.add_repository(v, pst)) ;
break;
}
}
if (this.data?.nodes !== undefined) {
switch (this.data?.nodes?.op) {
case 'add':
obj?.add_node(this.data.nodes.data, pst)
break;
case 'remove':
obj?.remove_node(this.data.nodes.names, this.data.nodes?.bTransferMyself, pst)
break;
case 'rename node':
this.data.nodes.data.forEach(v => obj?.rename_node(v.old, v.new, pst));
break;
case 'add from myself':
obj?.add_node2(this.data.nodes.addresses, pst);
break;
case 'add forward':
this.data.nodes.data.forEach(v => obj?.add_forward(v.prior_node_name, v.node_name, v.forward, v.threshold, v.remove_forward, pst))
break;
case 'remove forward':
this.data.nodes.data.forEach(v => obj?.remove_forward(v.prior_node_name, v.node_name, v.forward_name, pst))
break;
case 'remove pair':
this.data.nodes.pairs.forEach(v => obj?.remove_pair(v.prior_node_name, v.node_name, pst));
break;
}
}
if (this.data?.bPublished ) {
obj?.publish(passport)
}
var new_progress : Progress | undefined;
if (this.data?.progress_new !== undefined) {
new_progress = Progress?.New(txb, obj?.get_object(), perm, this.data?.progress_new.task_address, pst);
}
if (this.data?.progress_context_repository !== undefined) {
const p = this.data?.progress_context_repository.progress ?? new_progress?.get_object();
if (!p) ERROR(Errors.Fail, 'progress invalid: progress_context_repository');
Progress.From(txb, obj?.get_object(), perm, p!).set_context_repository(this.data?.progress_context_repository.repository, pst)
}
if (this.data?.progress_namedOperator !== undefined) {
const p = this.data?.progress_namedOperator.progress ?? new_progress?.get_object();
if (!p) ERROR(Errors.Fail, 'progress invalid: progress_namedOperator');
let pp = Progress.From(txb, obj?.get_object(), perm, p!);
this.data.progress_namedOperator.data.forEach(v => pp.set_namedOperator(v.name, v.operators, pst));
}
if (this.data?.progress_parent !== undefined) {
const p = this.data?.progress_parent.progress ?? new_progress?.get_object();
if (!p) ERROR(Errors.Fail, 'progress invalid: progress_parent');
if (this.data.progress_parent.parent) {
Progress.From(txb, obj?.get_object(), perm, p!).parent(this.data.progress_parent.parent);
} else {
Progress.From(txb, obj?.get_object(), perm, p!).parent_none();
}
}
if (this.data?.progress_task !== undefined) {
const p = this.data?.progress_task.progress ?? new_progress?.get_object();
if (!p) ERROR(Errors.Fail, 'progress invalid: progress_task');
Progress.From(txb, obj?.get_object(), perm, p!).bind_task(this.data.progress_task.task, pst)
}
if (this.data?.progress_hold !== undefined) {
const p = this.data?.progress_hold.progress ?? new_progress?.get_object();
if (!p) ERROR(Errors.Fail, 'progress invalid: progress_hold');
if (this.data?.progress_hold.adminUnhold) {
Progress.From(txb, obj?.get_object(), perm, p!).unhold(this.data.progress_hold.operation, pst)
} else {
Progress.From(txb, obj?.get_object(), perm, p!).hold(this.data.progress_hold.operation, this.data.progress_hold.bHold)
}
}
const addr = new_progress?.launch();
if (addr) {
await this.new_with_mark(txb, addr, this.data?.progress_new?.namedNew, account);
}
if (this.data?.progress_next !== undefined) {
Progress.From(txb, obj?.get_object(), perm, this.data?.progress_next.progress).next(this.data.progress_next.operation, this.data.progress_next.deliverable, pst)
}
if (this.data?.bPaused !== undefined) {
obj?.pause(this.data.bPaused, pst)
}
if (this.data?.clone_new !== undefined && obj) {
await this.new_with_mark(txb, obj?.clone(true, pst) as TxbAddress, (this.data?.clone_new as any)?.namedNew, account);
}
if (permission) {
await this.new_with_mark(txb, permission.launch(), (this.data?.permission as any)?.namedNew, account);
}
if (!object_address) {
await this.new_with_mark(txb, obj.launch(), (this.data?.object as any)?.namedNew, account);
}
}
}
}