wowok_agent
Version:
Making It Easy for AI Agents to Communicate, Collaborate, Trade, and Trust.
139 lines (138 loc) • 13.2 kB
JavaScript
import { z } from "zod";
import { WowTransactionBlockResponseSchema } from "../local/index.js";
import { BalanceTypeSchema, EntrypointSchema, ObjectBaseSchema, GuardTableItemSchema, NameSchema, NameOrAddressSchema, TokenTypeWithDefaultSchema } from "../common/index.js";
import { ENTRYPOINT } from "wowok";
export function strictParse(schema, input, fieldName = "input") {
let innerSchema = schema;
while (innerSchema._def?.typeName === 'ZodEffects') {
innerSchema = innerSchema._def.schema;
}
const shape = innerSchema._def.shape?.();
if (!shape) {
return schema.parse(input);
}
const allowedFields = Object.keys(shape);
const inputFields = Object.keys(input || {});
const unknownFields = inputFields.filter(f => !allowedFields.includes(f));
if (unknownFields.length > 0) {
throw new Error(`Unknown ${fieldName} field(s): ${unknownFields.join(', ')}`);
}
return schema.parse(input);
}
export const NamedObjectSchema = z.object({
name: NameSchema.optional().describe("The name of the object"),
tags: z.array(z.string()).optional().describe("The tags of the object"),
onChain: z.boolean().optional().describe("CRITICAL: Whether to sync the name to the blockchain. DEFAULT (undefined/false): The name is stored LOCALLY ONLY on your device (PRIVATE). If set to true: The name is published ON-CHAIN and becomes PUBLICLY VISIBLE to everyone. Only set to true for displaying the relationships you are willing to make public on the chain."),
replaceExistName: z.boolean().optional().describe("FORCE CLAIM: Set to true ONLY when the user explicitly expresses a STRONG INTENTION to forcefully take over an existing name (e.g., 'I must use this name', 'force rename', 'replace the existing one'). " +
"WARNING: This will UNBIND the name from its original object and rebind it to the new one, potentially breaking existing references. " +
"If not specified or false: the operation will FAIL with an error when the name is already in use (safe default behavior)."),
}).strict().describe("Assign a name and optional tags to a new object. By default, names are stored LOCALLY (private) on your device. " +
"Set 'onChain: true' to create a PUBLIC on-chain identity visible to everyone. " +
"IMPORTANT: If the requested name is already taken, the operation will FAIL by default. " +
"Only set 'replaceExistName: true' when the user EXPLICITLY demands to forcefully claim the name.");
export const NormalObjectSchema = z.union([
NameOrAddressSchema.describe("String format: Reference an EXISTING object by its name (local mark) or on-chain object ID. Example: 'my-service' or '0x1234...'"),
NamedObjectSchema.describe("Object format: CREATE a NEW object with specified properties. See NamedObjectSchema for details including 'name' (optional), 'tags' (optional), 'onChain' (whether to make name public), and 'replaceExistName' (force claim existing name)."),
]).describe("Two ways to specify an object: (1) STRING - Reference an EXISTING object by name or ID; (2) OBJECT - CREATE a NEW object using NamedObjectSchema structure with optional name, tags, and visibility settings.");
export const NamedObjectWithDescriptionSchema = NamedObjectSchema.extend({
description: z.string().optional().describe("The description of the object"),
}).strict().describe("Create a new object with a name and optional description. The name helps identify the object, while the description provides additional details about its purpose or functionality.");
export const DescriptionObjectSchema = z.union([
NameOrAddressSchema.describe("String format: Reference an EXISTING object by its name (local mark) or on-chain object ID. Example: 'my-object' or '0x1234...'"),
NamedObjectWithDescriptionSchema.describe("Object format: CREATE a NEW object with name, optional description, and visibility settings. Extends NamedObjectSchema with an additional 'description' field for detailed object information.")
]).describe("Two ways to specify an object: (1) STRING - Reference an EXISTING object by name or ID; (2) OBJECT - CREATE a NEW object with full configuration including optional name, tags, description, and visibility settings (local private by default, or public on-chain with onChain:true).");
export const TypeNamedObjectSchema = NamedObjectSchema.extend({
type_parameter: TokenTypeWithDefaultSchema.describe("Token type of the on-chain object, e.g. '0x2::wow::WOW'. Defines what token this object can use for payments."),
}).describe("Create a new named object (with optional tags) and specify a token type for payments (e.g., WOW).");
export const NamedObjectWithPermissionSchema = NamedObjectSchema.extend({
permission: DescriptionObjectSchema.optional(),
}).strict().describe("Use a Permission object to manage access control: (1) Specify an existing Permission object's name or ID; (2) Create a new Permission object (which can be named and tagged); or (3) Leave empty to automatically create a new unnamed Permission object.");
export const TypeNamedObjectWithPermissionSchema = NamedObjectWithPermissionSchema.extend({
type_parameter: TokenTypeWithDefaultSchema.describe("Type parameter (token type) of the on-chain object, e.g. '0x2::wow::WOW'. Defines what token this object can use for payments."),
}).strict().describe("Create a new named on-chain object with both a specific token type AND permission control. Use this when you need to specify a token type (e.g., WOW) for payment operations AND require permission management (who can manage/operate this object). For objects without permission management, use TypeNamedObjectSchema instead.");
export const CoinParamSchema = z.union([
z.object({
balance: BalanceTypeSchema,
}).describe("Specify an amount value."),
z.object({
coin: z.string().describe("Coin object ID or name(local mark). Use a specified Coin object."),
}),
]).describe("Specify the amount to pay from the transaction account, or the Coin ID owned by the transaction account. Used for payment.");
export const CallEnvSchema = z.object({
account: NameOrAddressSchema.optional().default(""),
permission_guard: z.array(z.string()).optional().describe("List of permission guard IDs. Used to extend additional operation permissions (requires verification and configuration in the Permission object)."),
no_cache: z.boolean().optional().describe("Whether to disable caching."),
network: EntrypointSchema.optional(),
referrer: NameOrAddressSchema.optional().describe("Referrer ID. If the user is using the network for the first time, the referrer ID will be recorded."),
}).strict().describe(`IMPORTANT: Execution environment includes: account for signing operations, network selection (${ENTRYPOINT}), additional Guard permissions, and more. Used to specify context information during the call. If account is not specified, the default account ("") will be used.`);
export const ObjectsOpSchema = z.union([
z.object({
op: z.literal("set").or(z.literal("add")).or(z.literal("remove")),
objects: z.array(NameOrAddressSchema),
}).describe("Set, add, or remove object ID list."),
z.object({
op: z.literal("clear"),
}).describe("Remove all objects."),
]).describe("Operate object list. Used to set, add, or remove objects.");
export const ResponseDataSchema = ObjectBaseSchema.extend({
change: z.union([z.literal("created"), z.literal("mutated"), z.string()]),
}).describe("Call result data. Contains basic object information and change type.");
export const CallResponseErrorSchema = z.object({
type: z.literal("error").describe("Type of call response: error"),
error: z.string(),
}).describe("Call error data. Contains error information.");
export const GuardSubmissionToFillSchema = z.object({
guard: NameOrAddressSchema.describe("Guard object name or ID."),
submission: z.array(GuardTableItemSchema).describe("User-submitted data required for Guard verification."),
}).strict().describe("Permission guard submission data.");
export const SubmissionCallSchema = z.object({
type: z.literal("submission").describe("Type of call response: submission"),
guard: z.array(z.object({
object: NameOrAddressSchema.describe("Guard object name or ID."),
impack: z.boolean().describe("Whether the verification result of this Guard participates in the final verification logic. If true, the verification result of this Guard will be included in the final verification result; if false, the verification result of this Guard will not be included."),
}).strict()),
submission: z.array(GuardSubmissionToFillSchema),
}).strict().describe("Guard verification submission data required to complete an operation. Contains: (1) 'guard' - array of Guard objects to verify, each with an object ID and an 'impack' flag indicating if its result affects the final outcome; (2) 'submission' - array of user data submissions matching the Guard's requirements. The operation proceeds only after all Guards with impack=true are successfully verified.");
export const TypedPermissionObjectSchema = z.union([
NameOrAddressSchema.describe("String format: Reference an EXISTING object by its name (local mark) or on-chain object ID. Use this when the object already exists and you want to reference it."),
TypeNamedObjectWithPermissionSchema.describe("Object format: CREATE a NEW object with COMPLETE configuration including: optional name, tags, description, token type for payments (e.g., '0x2::wow::WOW'), AND Permission-based access control. Use this for creating sophisticated objects with both payment token specification and permission management."),
]).describe("Two ways to specify an object: (1) STRING - Reference an EXISTING object by name or ID; (2) OBJECT - CREATE a NEW object with full configuration including name, tags, description, token type for payments, and Permission-based access control. The object format is used when you need both token specification AND permission management.");
export const WithPermissionObjectSchema = z.union([
NameOrAddressSchema.describe("String format: Reference an EXISTING object by its name (local mark) or on-chain object ID. Use when the Permission object already exists."),
NamedObjectWithPermissionSchema.describe("Object format: CREATE a NEW object with Permission-based access control. Includes optional name, tags, visibility settings, AND a Permission object (which itself can be referenced by string or created as a new object). Use this to create objects with managed access permissions."),
]).describe("Two ways to specify a Permission-managed object: (1) STRING - Reference an EXISTING Permission object by name or ID; (2) OBJECT - CREATE a NEW object with Permission access control, where the Permission can also be either referenced (string) or newly created (object). This is used when you need permission management but don't need to specify a token type.");
export const TypedDescriptionObjectSchema = z.union([
NameOrAddressSchema.describe("String format: Reference an EXISTING object by its name (local mark) or on-chain object ID. Use when the object already exists."),
TypeNamedObjectSchema.describe("Object format: CREATE a NEW object with token type specification for payments. Includes optional name, tags, visibility settings, AND a specific token type (e.g., '0x2::wow::WOW' or '0x2::usdt::USDT'). Use this when you need to specify what token the object will use for payments but don't need permission management."),
]).describe("Two ways to specify an object: (1) STRING - Reference an EXISTING object by name or ID; (2) OBJECT - CREATE a NEW object with token type specification for payments. The object format includes name, tags, visibility settings, and a required token type. This is used when you need to specify the payment token but don't need permission management.");
export const CallResultSchema = z.discriminatedUnion("type", [
SubmissionCallSchema,
WowTransactionBlockResponseSchema.extend({
type: z.literal("transaction"),
}),
CallResponseErrorSchema,
z.object({
type: z.literal("data"),
data: z.array(ResponseDataSchema),
}),
z.object({
type: z.literal("null"),
}),
]).describe("Call result. Can be Guard verification information (type: 'submission') that needs to be submitted by the user, result response, error information (type: 'error'), or null.");
export const ObjectsSchema = z.union([
z.object({
op: z.union([z.literal('add'), z.literal('set')]),
objects: z.array(NameOrAddressSchema).describe('List of object IDs or names to add or set'),
}).strict(),
z.object({
op: z.literal('remove'),
objects: z.array(NameOrAddressSchema).describe('List of object IDs or names to remove'),
}).strict(),
z.object({
op: z.literal('clear'),
}).strict(),
]);
export const CallOutputSchema = z.object({
result: CallResultSchema,
message: z.string().optional().describe("Message or hint information"),
}).strict().describe("On-chain Operation Result");