wowok_agent
Version:
Making It Easy for AI Agents to Communicate, Collaborate, Trade, and Trust.
348 lines (347 loc) • 17.2 kB
JavaScript
import { z } from "zod";
import { isValidAddress, ValueType as WowValueType, ObjectType as WowObjectType, ENTRYPOINT, isValidWowAddress, isValidName, isValidDescription, MAX_DESCRIPTION_LENGTH, isValidLongName, MAX_LONG_NAME_LENGTH } from "wowok";
const isValidMoveIdentifier = (s) => {
if (s.length === 0)
return false;
const firstChar = s[0];
if (firstChar === '_') {
return s.length > 1 && /^[a-zA-Z0-9_]+$/.test(s.slice(1));
}
if (/^[a-zA-Z]$/.test(firstChar)) {
return /^[a-zA-Z0-9_]*$/.test(s.slice(1));
}
return false;
};
export const DescriptionSchema = z
.string()
.refine(isValidDescription, {
message: `Description string (max ${MAX_DESCRIPTION_LENGTH} bcs characters)`
})
.describe(`Description string (max ${MAX_DESCRIPTION_LENGTH} bcs characters)`);
export const LongNameSchema = z
.string()
.refine(isValidLongName, {
message: `max ${MAX_LONG_NAME_LENGTH} bcs characters`
});
export const WowAddressSchema = z
.string()
.refine(isValidAddress, {
message: "Invalid ID format: must be '0x' prefix followed by 64 hex characters"
})
.describe("Valid ID: 0x prefix + 64 hex characters, or builtin ID (0x5-0x9, @0xaaa, @0xaab, @0x403, @0xacc, @0xc)");
const WOW_TOKEN_TYPE = "0x2::wow::WOW";
export const TokenTypeSchema = z
.string()
.refine((val) => {
if (val === WOW_TOKEN_TYPE)
return true;
const parts = val.split("::");
if (parts.length !== 3)
return false;
const [address, module, structName] = parts;
if (!isValidWowAddress(address))
return false;
if (!isValidMoveIdentifier(module))
return false;
if (!isValidMoveIdentifier(structName))
return false;
return true;
}, {
message: "Invalid token type format. Expected: {address}::{module}::{struct} where address is 0x+64hex, module/struct are valid Move identifiers, or '0x2::wow::WOW'"
})
.describe("Token type in format: {address}::{module}::{struct}. Example: 0x2::wow::WOW");
export const TokenTypeWithDefaultSchema = TokenTypeSchema
.default(WOW_TOKEN_TYPE)
.describe("Token type in format: {address}::{module}::{struct}. Default: 0x2::wow::WOW");
export const NameSchema = z
.string()
.refine(isValidName, "Name string (max 64 bcs characters, must not start with '0x')");
export const NotEmptyNameSchema = z.string().nonempty()
.refine(isValidName, "Name string (at least 1 character, max length 64 bcs characters)");
export const NameOrAddressSchema = z
.string()
.refine((val) => {
if (isValidWowAddress(val))
return true;
if (isValidName(val))
return true;
return false;
}, {
message: "Invalid ID format: must be '0x' prefix, or a builtin ID (0x5-0x9, @0xaaa, @0xaab, @0x403, @0xacc, @0xc)"
}).describe("Account/Object name or ID. If specifying an account, use empty string '' for the default account. " +
"If it starts with '0x', it will be treated as an ID. " +
"Otherwise, it will be treated as a name (max 64 bcs characters).");
export const AccountOrMark_AddressSchema = z.object({
name_or_address: NameOrAddressSchema.optional(),
local_mark_first: z.boolean().optional().describe("Whether to prioritize local marks, if true, prioritize local marks, otherwise prioritize global marks"),
}).strict().describe("Account or address lookup object. Use this to specify which account to use for an operation. " +
"EXAMPLE: { name_or_address: 'testor2' } - looks up account by name; " +
"EXAMPLE: { name_or_address: '0x1234...' } - uses address directly; " +
"If name_or_address is empty string '', uses the default local account.");
export const ManyAccountOrMark_AddressSchema = z.object({
entities: z.array(AccountOrMark_AddressSchema),
check_all_founded: z.boolean().optional().describe("Whether to check all entities are found, if true, all entities must be found (abort and throw exception if any ID not found); if false, only return found IDs"),
}).strict().describe("Used to batch find account or object IDs by name");
export const AccountOrMark_AddressAISchema = z.union([
z.string().describe("Account name, address (0x...), or mark name. " +
"When using string format, local marks are searched first. " +
"EXAMPLE: 'alice' - searches local marks first, then global; " +
"EXAMPLE: '0x1234...' - uses address directly"),
AccountOrMark_AddressSchema
]).describe("Account or address lookup. Can be a simple string (recommended for AI) " +
"or full object with explicit local_mark_first control");
export const ManyAccountOrMark_AddressAISchema = z.union([
z.array(z.string()).describe("Array of account names, addresses, or mark names. " +
"Local marks are searched first for each entry"),
ManyAccountOrMark_AddressSchema
]).describe("Batch account or address lookup. Can be an array of strings (recommended for AI) " +
"or full object with explicit control");
export const ObjectOwnerSchema = z.union([
z.object({
AddressOwner: z.string().describe("Address owner"),
}).strict(),
z.object({
ObjectOwner: z.string().describe("Object owner"),
}).strict(),
z.object({
Shared: z.object({
initial_shared_version: z.union([z.string(), z.number()]).describe("Version when object became shared"),
}).strict().describe("Shared object"),
}).strict(),
z.literal("Immutable"),
z.object({
ConsensusAddressOwner: z.object({
owner: z.string().describe("Consensus ID owner"),
start_version: z.union([z.string(), z.number()]).describe("Version when object recently became consensus object"),
}).strict().describe("Consensus ID owner"),
}).strict(),
]).describe("Object owner");
const ValueTypeStringNames = [
"Bool", "Address", "String", "U8", "U16", "U32", "U64", "U128", "U256",
"VecBool", "VecAddress", "VecString", "VecU8", "VecU16", "VecU32", "VecU64", "VecU128", "VecU256", "VecVecU8"
];
export const ValueTypeUserSchema = z.union([
z.literal(WowValueType.Bool).describe("Bool (0)"),
z.literal(WowValueType.Address).describe("Address (1)"),
z.literal(WowValueType.String).describe("String (2)"),
z.literal(WowValueType.U8).describe("U8 (3)"),
z.literal(WowValueType.U16).describe("U16 (4)"),
z.literal(WowValueType.U32).describe("U32 (5)"),
z.literal(WowValueType.U64).describe("U64 (6)"),
z.literal(WowValueType.U128).describe("U128 (7)"),
z.literal(WowValueType.U256).describe("U256 (8)"),
z.literal(WowValueType.VecBool).describe("VecBool (9)"),
z.literal(WowValueType.VecAddress).describe("VecAddress (10)"),
z.literal(WowValueType.VecString).describe("VecString (11)"),
z.literal(WowValueType.VecU8).describe("VecU8 (12)"),
z.literal(WowValueType.VecU16).describe("VecU16 (13)"),
z.literal(WowValueType.VecU32).describe("VecU32 (14)"),
z.literal(WowValueType.VecU64).describe("VecU64 (15)"),
z.literal(WowValueType.VecU128).describe("VecU128 (16)"),
z.literal(WowValueType.VecU256).describe("VecU256 (17)"),
z.literal(WowValueType.VecVecU8).describe("VecVecU8 (18)"),
z.literal("Bool").describe("Bool"),
z.literal("Address").describe("Address"),
z.literal("String").describe("String"),
z.literal("U8").describe("U8"),
z.literal("U16").describe("U16"),
z.literal("U32").describe("U32"),
z.literal("U64").describe("U64"),
z.literal("U128").describe("U128"),
z.literal("U256").describe("U256"),
z.literal("VecBool").describe("VecBool"),
z.literal("VecAddress").describe("VecAddress"),
z.literal("VecString").describe("VecString"),
z.literal("VecU8").describe("VecU8"),
z.literal("VecU16").describe("VecU16"),
z.literal("VecU32").describe("VecU32"),
z.literal("VecU64").describe("VecU64"),
z.literal("VecU128").describe("VecU128"),
z.literal("VecU256").describe("VecU256"),
z.literal("VecVecU8").describe("VecVecU8"),
z.literal("bool").describe("bool"),
z.literal("address").describe("address"),
z.literal("string").describe("string"),
z.literal("u8").describe("u8"),
z.literal("u16").describe("u16"),
z.literal("u32").describe("u32"),
z.literal("u64").describe("u64"),
z.literal("u128").describe("u128"),
z.literal("u256").describe("u256"),
z.literal("vecbool").describe("vecbool"),
z.literal("vecaddress").describe("vecaddress"),
z.literal("vecstring").describe("vecstring"),
z.literal("vecu8").describe("vecu8"),
z.literal("vecu16").describe("vecu16"),
z.literal("vecu32").describe("vecu32"),
z.literal("vecu64").describe("vecu64"),
z.literal("vecu128").describe("vecu128"),
z.literal("vecu256").describe("vecu256"),
z.literal("vecvecu8").describe("vecvecu8"),
]).describe("User available value type (number or string, e.g., 6 or 'U64' or 'u64')");
export const ValueTypeSchema = ValueTypeUserSchema.or(z.literal(WowValueType.Value).describe("Value (19)")).or(z.literal("Value").describe("Value"))
.describe("Value type (number or string, e.g., 6 or 'U64')");
export const ObjectTypeSchema = z.enum([
WowObjectType.Permission,
WowObjectType.Repository,
WowObjectType.Arb,
WowObjectType.Arbitration,
WowObjectType.Service,
WowObjectType.Machine,
WowObjectType.Order,
WowObjectType.Progress,
WowObjectType.Payment,
WowObjectType.Treasury,
WowObjectType.Guard,
WowObjectType.Demand,
WowObjectType.Passport,
WowObjectType.Allocation,
WowObjectType.Resource,
WowObjectType.Reward,
WowObjectType.Discount,
WowObjectType.EntityRegistrar,
WowObjectType.EntityLinker,
WowObjectType.Proof,
WowObjectType.WReceivedObject,
WowObjectType.Contact,
WowObjectType.TableItem_ProgressHistory,
WowObjectType.TableItem_PermissionPerm,
WowObjectType.TableItem_DemandPresenter,
WowObjectType.TableItem_MachineNode,
WowObjectType.TableItem_TreasuryHistory,
WowObjectType.TableItem_RepositoryData,
WowObjectType.TableItem_RewardRecord,
WowObjectType.TableItem_EntityLinker,
WowObjectType.TableItem_AddressMark,
WowObjectType.TableItem_EntityRegistrar,
]).describe("Wowok object type");
export const BalanceTypeSchema = z.union([z.number(), z.string()]).describe("Balance type");
export const QueryIdSchema = z.number().int().min(0).describe("Query ID");
export const CacheExpireTypeSchema = z.union([z.number(), z.literal("INFINITE")]).describe("Cache expiration time type");
export const ValueContainerSchema = z.lazy(() => z.object({
valueType: ValueTypeSchema.describe("Value type"),
value: SupportedValueSchema.describe("Value"),
}).strict().describe("Value container with type and value"));
export const SupportedValueUserSchema = z.union([
z.boolean(),
z.union([AccountOrMark_AddressSchema, z.string()]),
z.string(),
z.number(),
z.array(z.boolean()),
z.union([ManyAccountOrMark_AddressSchema, z.array(z.string())]),
z.array(z.string()),
z.array(z.number()),
z.array(z.array(z.number())),
]).describe("User available supported value type");
export const SupportedValueSchema = SupportedValueUserSchema.or(ValueContainerSchema).describe("Supported value type");
export const GuardIdentifierSchema = z.number().int().min(0).max(255).describe("Identifier (0-255) for data lookup in Guard table.");
export const GuardTableItemBaseSchema = z.object({
identifier: GuardIdentifierSchema,
b_submission: z.boolean().describe("Whether user submission is required for this data"),
value_type: ValueTypeUserSchema.describe("Type of the value"),
value: SupportedValueUserSchema.optional().describe("The actual value data"),
name: z.string().default("").describe("Name or description of this data"),
}).strict().describe("Guard table item");
export const GuardTableItemSchema = GuardTableItemBaseSchema.extend({
object_type: ObjectTypeSchema.optional().describe("Object type when value_type is Address and represents a specific object"),
}).strict().describe("Guard table item");
export const EntrypointSchema = z.enum([
ENTRYPOINT.Localnet,
ENTRYPOINT.Testnet,
]).describe("Network entrypoint: Specifies which network the operation occurs on");
export const FaucetNetworkSchema = z.enum([
ENTRYPOINT.Localnet,
ENTRYPOINT.Testnet,
]).describe("Network entrypoint for Faucet: Specifies which network the operation occurs on");
export const ObjectBaseSchema = z.object({
object: z.string().describe("Object ID"),
type: ObjectTypeSchema.optional().describe("Object type"),
type_raw: z.string().optional().describe("Raw object type"),
owner: z.union([ObjectOwnerSchema, z.null()]).optional().describe("Object owner"),
version: z.string().optional().describe("Object version"),
previousTransaction: z.string().optional().describe("Previous transaction ID"),
cache_expire: CacheExpireTypeSchema.optional().describe("Cache expiration time"),
query_name: z.string().optional().describe("Original query name or address used to retrieve this object"),
content_raw: z.any().optional().describe("Raw content data for unknown object types"),
_guard_node_comments: z.array(z.object({
type: z.string(),
description: z.string()
})).optional().describe("Additional comments for Guard node instructions"),
}).passthrough().describe("Object base information");
export const QueryEnvSchema = z.object({
no_cache: z.boolean().optional().describe("Whether to disable cache"),
network: EntrypointSchema.optional(),
}).strict().describe("Query environment parameters");
export const QueryReceivedSchema = QueryEnvSchema.extend({
name_or_address: AccountOrMark_AddressAISchema,
all_type: z.boolean().optional().describe("Whether to query all types of received objects"),
cursor: z.union([z.string(), z.null()]).optional().describe("Pagination cursor"),
limit: z.union([z.number(), z.null()]).optional().describe("Number of records returned per page"),
}).strict().describe("Request parameters for querying object's received objects");
export const ReceivedBalanceObjectSchema = z.object({
id: z.string().describe("Received CoinWrapper object ID"),
balance: BalanceTypeSchema,
payment: z.string().describe("Payment object ID"),
}).strict().describe("Received CoinWrapper object record");
export const CoinWrapperTokenTypeSchema = z
.string()
.refine((val) => {
const match = val.match(/^CoinWrapper<(.+)>$/);
if (match) {
const inner = match[1];
if (inner === WOW_TOKEN_TYPE)
return true;
const parts = inner.split("::");
if (parts.length !== 3)
return false;
const [address, module, structName] = parts;
if (!isValidWowAddress(address))
return false;
if (!isValidMoveIdentifier(module))
return false;
if (!isValidMoveIdentifier(structName))
return false;
return true;
}
if (val === WOW_TOKEN_TYPE)
return true;
const parts = val.split("::");
if (parts.length !== 3)
return false;
const [address, module, structName] = parts;
if (!isValidWowAddress(address))
return false;
if (!isValidMoveIdentifier(module))
return false;
if (!isValidMoveIdentifier(structName))
return false;
return true;
}, {
message: "Invalid token type format. Expected: CoinWrapper<{address}::{module}::{struct}> or {address}::{module}::{struct}. Example: CoinWrapper<0x2::wow::WOW> or 0x2::wow::WOW"
})
.describe("Token type in format: CoinWrapper<{address}::{module}::{struct}> or {address}::{module}::{struct}. Example: CoinWrapper<0x2::wow::WOW>");
export const ReceivedBalanceSchema = z.object({
balance: BalanceTypeSchema,
token_type: CoinWrapperTokenTypeSchema.describe("Asset type of Coin objects. Supports CoinWrapper<...> format for order receive operations."),
received: z.array(ReceivedBalanceObjectSchema).describe("Received records of Coin objects"),
}).strict().describe("Received record of Coin objects");
export const ReceivedBalanceOrRecentlySchema = z.union([
ReceivedBalanceSchema,
z.literal("recently")
]).describe("Specified received balance record or all recently received balance record");
export const ReceivedNormalSchema = z.object({
id: z.string().nonempty().describe("Received object ID"),
type: z.string().nonempty().describe("Object type"),
content_raw: z.any().optional().describe("Raw content data")
}).strict().describe("Received normal object record");
export const ReceivedObjectsOrRecentlySchema = z.union([
z.array(ReceivedNormalSchema),
ReceivedBalanceSchema,
z.literal("recently"),
]).describe("Specified received object records or all recently received object records");
export const QueryReceivedResultSchema = z.object({
result: z.union([
ReceivedBalanceSchema,
z.array(ReceivedNormalSchema),
]).describe("Received CoinWrapper object record or received other objects array")
}).strict().describe("Query received result");