@conquest-eth/tools 0.0.0 → 0.0.2

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.
Files changed (178) hide show
  1. package/README.md +20 -51
  2. package/dist/cli-tool-generator.d.ts +2 -1
  3. package/dist/cli-tool-generator.d.ts.map +1 -1
  4. package/dist/cli.js +61 -32
  5. package/dist/cli.js.map +1 -1
  6. package/dist/contracts/space-info.d.ts.map +1 -1
  7. package/dist/contracts/space-info.js +22 -1
  8. package/dist/contracts/space-info.js.map +1 -1
  9. package/dist/fleet/resolve.d.ts +1 -1
  10. package/dist/fleet/resolve.d.ts.map +1 -1
  11. package/dist/fleet/resolve.js +5 -4
  12. package/dist/fleet/resolve.js.map +1 -1
  13. package/dist/fleet/send.d.ts.map +1 -1
  14. package/dist/fleet/send.js +8 -8
  15. package/dist/fleet/send.js.map +1 -1
  16. package/dist/index.d.ts +6 -32
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +21 -128
  19. package/dist/index.js.map +1 -1
  20. package/dist/mcp.d.ts +14 -0
  21. package/dist/mcp.d.ts.map +1 -0
  22. package/dist/mcp.js +29 -0
  23. package/dist/mcp.js.map +1 -0
  24. package/dist/planet/acquire.d.ts +3 -2
  25. package/dist/planet/acquire.d.ts.map +1 -1
  26. package/dist/planet/acquire.js +6 -4
  27. package/dist/planet/acquire.js.map +1 -1
  28. package/dist/planet/exit.d.ts.map +1 -1
  29. package/dist/planet/exit.js +1 -0
  30. package/dist/planet/exit.js.map +1 -1
  31. package/dist/planet/manager.d.ts +63 -0
  32. package/dist/planet/manager.d.ts.map +1 -1
  33. package/dist/planet/manager.js +125 -2
  34. package/dist/planet/manager.js.map +1 -1
  35. package/dist/planet/withdraw.d.ts +17 -0
  36. package/dist/planet/withdraw.d.ts.map +1 -0
  37. package/dist/planet/withdraw.js +25 -0
  38. package/dist/planet/withdraw.js.map +1 -0
  39. package/dist/storage/interface.d.ts +6 -0
  40. package/dist/storage/interface.d.ts.map +1 -1
  41. package/dist/storage/json-storage.d.ts +1 -0
  42. package/dist/storage/json-storage.d.ts.map +1 -1
  43. package/dist/storage/json-storage.js +10 -1
  44. package/dist/storage/json-storage.js.map +1 -1
  45. package/dist/tool-handling/cli-tool-generator.d.ts +22 -0
  46. package/dist/tool-handling/cli-tool-generator.d.ts.map +1 -0
  47. package/dist/tool-handling/cli-tool-generator.js +345 -0
  48. package/dist/tool-handling/cli-tool-generator.js.map +1 -0
  49. package/dist/tool-handling/cli.d.ts +19 -0
  50. package/dist/tool-handling/cli.d.ts.map +1 -0
  51. package/dist/tool-handling/cli.js +472 -0
  52. package/dist/tool-handling/cli.js.map +1 -0
  53. package/dist/tool-handling/index.d.ts +15 -0
  54. package/dist/tool-handling/index.d.ts.map +1 -0
  55. package/dist/tool-handling/index.js +32 -0
  56. package/dist/tool-handling/index.js.map +1 -0
  57. package/dist/tool-handling/mcp.d.ts +22 -0
  58. package/dist/tool-handling/mcp.d.ts.map +1 -0
  59. package/dist/tool-handling/mcp.js +88 -0
  60. package/dist/tool-handling/mcp.js.map +1 -0
  61. package/dist/tool-handling/types.d.ts +72 -0
  62. package/dist/tool-handling/types.d.ts.map +1 -0
  63. package/dist/tool-handling/types.js +10 -0
  64. package/dist/tool-handling/types.js.map +1 -0
  65. package/dist/tools/acquire_planets.d.ts +7 -5
  66. package/dist/tools/acquire_planets.d.ts.map +1 -1
  67. package/dist/tools/acquire_planets.js +28 -42
  68. package/dist/tools/acquire_planets.js.map +1 -1
  69. package/dist/tools/exit_planets.d.ts +7 -3
  70. package/dist/tools/exit_planets.d.ts.map +1 -1
  71. package/dist/tools/exit_planets.js +20 -9
  72. package/dist/tools/exit_planets.js.map +1 -1
  73. package/dist/tools/get_my_planets.d.ts +3 -2
  74. package/dist/tools/get_my_planets.d.ts.map +1 -1
  75. package/dist/tools/get_my_planets.js +5 -4
  76. package/dist/tools/get_my_planets.js.map +1 -1
  77. package/dist/tools/get_native_token_balance.d.ts +6 -0
  78. package/dist/tools/get_native_token_balance.d.ts.map +1 -0
  79. package/dist/tools/get_native_token_balance.js +64 -0
  80. package/dist/tools/get_native_token_balance.js.map +1 -0
  81. package/dist/tools/get_pending_exits.d.ts +2 -1
  82. package/dist/tools/get_pending_exits.d.ts.map +1 -1
  83. package/dist/tools/get_pending_exits.js +5 -4
  84. package/dist/tools/get_pending_exits.js.map +1 -1
  85. package/dist/tools/get_pending_fleets.d.ts +2 -1
  86. package/dist/tools/get_pending_fleets.d.ts.map +1 -1
  87. package/dist/tools/get_pending_fleets.js +5 -4
  88. package/dist/tools/get_pending_fleets.js.map +1 -1
  89. package/dist/tools/get_planets_around.d.ts +8 -4
  90. package/dist/tools/get_planets_around.d.ts.map +1 -1
  91. package/dist/tools/get_planets_around.js +40 -15
  92. package/dist/tools/get_planets_around.js.map +1 -1
  93. package/dist/tools/get_play_token_balance.d.ts +6 -0
  94. package/dist/tools/get_play_token_balance.d.ts.map +1 -0
  95. package/dist/tools/get_play_token_balance.js +80 -0
  96. package/dist/tools/get_play_token_balance.js.map +1 -0
  97. package/dist/tools/index.d.ts +7 -1
  98. package/dist/tools/index.d.ts.map +1 -1
  99. package/dist/tools/index.js +7 -1
  100. package/dist/tools/index.js.map +1 -1
  101. package/dist/tools/missiv_get_user.d.ts +6 -0
  102. package/dist/tools/missiv_get_user.d.ts.map +1 -0
  103. package/dist/tools/missiv_get_user.js +50 -0
  104. package/dist/tools/missiv_get_user.js.map +1 -0
  105. package/dist/tools/missiv_register.d.ts +6 -0
  106. package/dist/tools/missiv_register.d.ts.map +1 -0
  107. package/dist/tools/missiv_register.js +103 -0
  108. package/dist/tools/missiv_register.js.map +1 -0
  109. package/dist/tools/resolve_fleet.d.ts +3 -2
  110. package/dist/tools/resolve_fleet.d.ts.map +1 -1
  111. package/dist/tools/resolve_fleet.js +5 -4
  112. package/dist/tools/resolve_fleet.js.map +1 -1
  113. package/dist/tools/send_fleet.d.ts +3 -2
  114. package/dist/tools/send_fleet.d.ts.map +1 -1
  115. package/dist/tools/send_fleet.js +16 -15
  116. package/dist/tools/send_fleet.js.map +1 -1
  117. package/dist/tools/simulate.d.ts +14 -0
  118. package/dist/tools/simulate.d.ts.map +1 -0
  119. package/dist/tools/simulate.js +123 -0
  120. package/dist/tools/simulate.js.map +1 -0
  121. package/dist/tools/simulate_multiple.d.ts +17 -0
  122. package/dist/tools/simulate_multiple.d.ts.map +1 -0
  123. package/dist/tools/simulate_multiple.js +166 -0
  124. package/dist/tools/simulate_multiple.js.map +1 -0
  125. package/dist/tools/verify_exit_status.d.ts +5 -3
  126. package/dist/tools/verify_exit_status.d.ts.map +1 -1
  127. package/dist/tools/verify_exit_status.js +12 -8
  128. package/dist/tools/verify_exit_status.js.map +1 -1
  129. package/dist/tools/withdraw.d.ts +9 -0
  130. package/dist/tools/withdraw.d.ts.map +1 -0
  131. package/dist/tools/withdraw.js +86 -0
  132. package/dist/tools/withdraw.js.map +1 -0
  133. package/dist/types.d.ts +31 -28
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/types.js +1 -33
  136. package/dist/types.js.map +1 -1
  137. package/dist/util/time.d.ts +0 -30
  138. package/dist/util/time.d.ts.map +1 -1
  139. package/dist/util/time.js +0 -36
  140. package/dist/util/time.js.map +1 -1
  141. package/package.json +80 -77
  142. package/src/cli.ts +88 -59
  143. package/src/contracts/space-info.ts +24 -1
  144. package/src/fleet/resolve.ts +5 -4
  145. package/src/fleet/send.ts +9 -8
  146. package/src/index.ts +28 -162
  147. package/src/mcp.ts +46 -0
  148. package/src/planet/acquire.ts +6 -6
  149. package/src/planet/exit.ts +1 -0
  150. package/src/planet/manager.ts +163 -0
  151. package/src/planet/withdraw.ts +33 -0
  152. package/src/storage/interface.ts +7 -0
  153. package/src/storage/json-storage.ts +11 -1
  154. package/src/tool-handling/cli.ts +559 -0
  155. package/src/tool-handling/index.ts +45 -0
  156. package/src/tool-handling/mcp.ts +127 -0
  157. package/src/tool-handling/types.ts +86 -0
  158. package/src/tools/acquire_planets.ts +34 -60
  159. package/src/tools/exit_planets.ts +25 -12
  160. package/src/tools/get_native_token_balance.ts +72 -0
  161. package/src/tools/get_pending_exits.ts +8 -5
  162. package/src/tools/get_pending_fleets.ts +8 -5
  163. package/src/tools/get_planets_around.ts +45 -16
  164. package/src/tools/get_play_token_balance.ts +90 -0
  165. package/src/tools/index.ts +7 -1
  166. package/src/tools/missiv_get_user.ts +68 -0
  167. package/src/tools/missiv_register.ts +122 -0
  168. package/src/tools/resolve_fleet.ts +8 -5
  169. package/src/tools/send_fleet.ts +21 -18
  170. package/src/tools/simulate.ts +141 -0
  171. package/src/tools/simulate_multiple.ts +197 -0
  172. package/src/tools/verify_exit_status.ts +15 -11
  173. package/src/tools/withdraw.ts +100 -0
  174. package/src/types.ts +33 -71
  175. package/src/util/time.ts +0 -46
  176. package/src/cli-tool-generator.ts +0 -287
  177. package/src/helpers/index.ts +0 -59
  178. package/src/tools/get_my_planets.ts +0 -30
@@ -0,0 +1,127 @@
1
+ import {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import {Tool, ToolResult, ToolEnvironment} from './types.js';
3
+ import {CallToolResult} from '@modelcontextprotocol/sdk/types.js';
4
+
5
+ /**
6
+ * Create tool environment with MCP logging support
7
+ * @template TEnv - Environment properties type
8
+ * @param server - MCP server instance for sending logging messages
9
+ * @param env - Environment properties to spread into the tool environment
10
+ * @param sessionId - Optional session ID for targeting specific client
11
+ */
12
+ function createToolEnvironmentWithMCP<TEnv extends Record<string, any>>(
13
+ server: McpServer,
14
+ env: TEnv,
15
+ sessionId?: string,
16
+ ): ToolEnvironment<TEnv> {
17
+ return {
18
+ sendStatus: async (message: string) => {
19
+ try {
20
+ await server.sendLoggingMessage(
21
+ {
22
+ level: 'info',
23
+ data: message,
24
+ },
25
+ sessionId,
26
+ );
27
+ } catch (error) {
28
+ // Silently ignore logging errors to not disrupt tool execution
29
+ }
30
+ },
31
+ ...env,
32
+ };
33
+ }
34
+
35
+ /**
36
+ * Convert ToolResult to CallToolResult format
37
+ */
38
+ function convertToCallToolResult(result: ToolResult): CallToolResult {
39
+ if (result.success === false) {
40
+ return {
41
+ content: [
42
+ {
43
+ type: 'text',
44
+ text: JSON.stringify({
45
+ error: result.error,
46
+ ...(result.stack ? {stack: result.stack} : {}),
47
+ }),
48
+ },
49
+ ],
50
+ isError: true,
51
+ };
52
+ }
53
+
54
+ return {
55
+ content: [
56
+ {
57
+ type: 'text',
58
+ text: JSON.stringify(
59
+ result.result,
60
+ (_key, value) => (typeof value === 'bigint' ? value.toString() : value),
61
+ 2,
62
+ ),
63
+ },
64
+ ],
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Register tool with MCP server
70
+ * @template TEnv - Environment properties type
71
+ */
72
+ export function registerMCPTool<TEnv extends Record<string, any>>({
73
+ server,
74
+ name,
75
+ tool,
76
+ env,
77
+ }: {
78
+ server: McpServer;
79
+ name: string;
80
+ tool: Tool<any, TEnv>;
81
+ env: TEnv;
82
+ }): void {
83
+ server.registerTool(
84
+ name,
85
+ {
86
+ description: tool.description,
87
+ inputSchema: tool.schema as any,
88
+ },
89
+ async (params: unknown, mcpExtra: any) => {
90
+ // Create tool environment with proper MCP sendStatus
91
+ const toolEnv = createToolEnvironmentWithMCP(server, env, mcpExtra?.sessionId);
92
+
93
+ try {
94
+ const result = await tool.execute(toolEnv, params as any);
95
+ return convertToCallToolResult(result);
96
+ } catch (error) {
97
+ const errorResult: {success: false; error: string; stack?: string} = {
98
+ success: false,
99
+ error: error instanceof Error ? error.message : String(error),
100
+ stack: error instanceof Error ? error.stack : undefined,
101
+ };
102
+ return convertToCallToolResult(errorResult);
103
+ }
104
+ },
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Register all tool from a tools object
110
+ * @template TEnv - Environment type passed to tools
111
+ */
112
+ export function registerAllMCPTools<TEnv extends Record<string, any>>({
113
+ server,
114
+ tools,
115
+ env,
116
+ }: {
117
+ server: McpServer;
118
+ tools: Record<string, Tool<any, TEnv>>;
119
+ env: TEnv;
120
+ }): void {
121
+ for (const [name, tool] of Object.entries(tools)) {
122
+ // Skip the file that's not a tool
123
+ if (name === 'default') continue;
124
+
125
+ registerMCPTool({server, name, tool, env});
126
+ }
127
+ }
@@ -0,0 +1,86 @@
1
+ import {z} from 'zod';
2
+ import type {CallToolResult} from '@modelcontextprotocol/sdk/types.js';
3
+ import type {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js';
4
+
5
+ /**
6
+ * Environment provided to tool execute functions
7
+ * Generic type TEnv allows customization of the environment properties
8
+ * @template TEnv - Additional environment properties spread into the environment
9
+ */
10
+ export type ToolEnvironment<TEnv extends Record<string, any> = Record<string, any>> = {
11
+ /** function to send status updates during tool execution */
12
+ sendStatus: (message: string) => Promise<void>;
13
+ } & TEnv;
14
+
15
+ /**
16
+ * Result returned by tool execute functions
17
+ * Success case: {success: true, result: Record<string, any>}
18
+ * Error case: {success: false, error: string, stack?: string}
19
+ */
20
+ export type ToolResult =
21
+ | {success: true; result: Record<string, any>}
22
+ | {success: false; error: string; stack?: string};
23
+
24
+ /**
25
+ * Schema types that can be used for tool input parameters
26
+ * Supports ZodObject directly or ZodUnion of ZodObjects (for mutually exclusive params)
27
+ */
28
+ export type ToolSchema =
29
+ | z.ZodObject<any>
30
+ | z.ZodUnion<readonly [z.ZodObject<any>, ...z.ZodObject<any>[]]>;
31
+
32
+ /**
33
+ * Tool definition with execute, schema, and description
34
+ * @template S - Zod schema type for input parameters
35
+ * @template TEnv - Environment type passed to execute function
36
+ */
37
+ export type Tool<
38
+ S extends ToolSchema = z.ZodObject<any>,
39
+ TEnv extends Record<string, any> = Record<string, any>,
40
+ > = {
41
+ /** Description of what the tool does */
42
+ description: string;
43
+ /** Zod schema for input parameters */
44
+ schema: S;
45
+ /**
46
+ * Execute function that receives environment and parameters
47
+ * @param env - Tool environment with sendStatus and custom properties
48
+ * @param params - Parameters inferred from schema
49
+ * @returns ToolResult with success/error state
50
+ */
51
+ execute: (env: ToolEnvironment<TEnv>, params: z.infer<S>) => Promise<ToolResult>;
52
+ };
53
+
54
+ /**
55
+ * Helper function to create a tool with automatic type inference
56
+ * Use this instead of directly creating Tool objects to get proper TypeScript types
57
+ * @template S - Zod schema type for input parameters
58
+ * @template TEnv - Environment type passed to execute function
59
+ */
60
+ export function createTool<
61
+ S extends ToolSchema,
62
+ TEnv extends Record<string, any> = Record<string, any>,
63
+ >(config: {
64
+ description: string;
65
+ schema: S;
66
+ execute: (env: ToolEnvironment<TEnv>, params: z.infer<S>) => Promise<ToolResult>;
67
+ }): Tool<S, TEnv> {
68
+ return config;
69
+ }
70
+
71
+ /**
72
+ * Parameters for tool registration
73
+ * @template S - Zod schema type for input parameters
74
+ * @template TEnv - Environment type passed to execute function
75
+ */
76
+ export type RegisterToolParams<
77
+ S extends ToolSchema,
78
+ TEnv extends Record<string, any> = Record<string, any>,
79
+ > = {
80
+ /** MCP server instance */
81
+ server: McpServer;
82
+ /** Tool name (snake_case) */
83
+ name: string;
84
+ /** Tool definition */
85
+ tool: Tool<S, TEnv>;
86
+ };
@@ -1,74 +1,48 @@
1
1
  import {z} from 'zod';
2
- import {createTool} from '../types.js';
3
- import {stringifyWithBigInt} from '../helpers/index.js';
2
+ import {formatUnits} from 'viem';
3
+ import {createTool} from '../tool-handling/types.js';
4
+ import type {ConquestEnv} from '../types.js';
4
5
 
5
- export const acquire_planets = createTool({
6
+ const schema = z.object({
7
+ coordinates: z
8
+ .array(
9
+ z.object({
10
+ x: z.number().describe('X coordinate of the planet'),
11
+ y: z.number().describe('Y coordinate of the planet'),
12
+ }),
13
+ )
14
+ .describe('Array of planet coordinates to acquire'),
15
+ });
16
+
17
+ export const acquire_planets = createTool<typeof schema, ConquestEnv>({
6
18
  description:
7
- 'Acquire (stake) multiple planets in the Conquest game. This allows you to take ownership of unclaimed planets.',
8
- schema: z.object({
9
- planetIds: z
10
- .array(z.union([z.string(), z.number()]))
11
- .describe('Array of planet location IDs to acquire (as hex strings or numbers)'),
12
- amountToMint: z
13
- .number()
14
- .optional()
15
- .describe(
16
- 'Amount of native token to spend to acquire the planets. If not provided, will be calculated automatically based on planet stats.',
17
- ),
18
- tokenAmount: z
19
- .number()
20
- .optional()
21
- .describe(
22
- 'Amount of staking token to spend to acquire the planets. If not provided, will be calculated automatically based on planet stats.',
23
- ),
24
- }),
25
- execute: async (env, {planetIds, amountToMint, tokenAmount}) => {
19
+ 'Acquire (stake) multiple planets in the Conquest game. This allows you to take ownership of unclaimed planets. Automatically uses all available play token balance first, then mints the remainder with native tokens.',
20
+ schema,
21
+ execute: async (env, {coordinates}) => {
26
22
  try {
27
- // Convert planet IDs to BigInt
28
- const planetIdsBigInt = planetIds.map((id) =>
29
- typeof id === 'string' ? BigInt(id) : BigInt(id),
30
- );
31
-
32
- let result: {
33
- hash: `0x${string}`;
34
- planetsAcquired: bigint[];
35
- amountToMint: bigint;
36
- tokenAmount: bigint;
37
- };
38
-
39
- // If BOTH amounts are provided, use them; otherwise use auto-calculation
40
- if (amountToMint !== undefined && tokenAmount !== undefined) {
41
- // Use provided amounts
42
- // TODO decimal handling, for now BigInt()
43
- const acquireResult = await env.planetManager.acquire(
44
- planetIdsBigInt,
45
- BigInt(amountToMint),
46
- BigInt(tokenAmount),
47
- );
48
- result = {
49
- hash: acquireResult.hash,
50
- planetsAcquired: acquireResult.planetsAcquired,
51
- amountToMint: BigInt(amountToMint),
52
- tokenAmount: BigInt(tokenAmount),
53
- };
54
- } else {
55
- // Use auto-calculation
56
- const autoResult = await env.planetManager.acquireWithAutoCalc(planetIdsBigInt);
57
- result = {
58
- hash: autoResult.hash,
59
- planetsAcquired: autoResult.planetsAcquired,
60
- amountToMint: autoResult.costs.amountToMint,
61
- tokenAmount: autoResult.costs.tokenAmount,
62
- };
23
+ // Convert x,y coordinates to planet IDs
24
+ const planetIdsBigInt: bigint[] = [];
25
+ for (const coord of coordinates) {
26
+ const planetId = env.planetManager.getPlanetIdByCoordinates(coord.x, coord.y);
27
+ if (planetId === undefined) {
28
+ throw new Error(`No planet found at coordinates (${coord.x}, ${coord.y})`);
29
+ }
30
+ planetIdsBigInt.push(planetId);
63
31
  }
64
32
 
33
+ // Acquire planets using max play token balance first, then minting remainder
34
+ const result = await env.planetManager.acquireWithMaxPlayToken(planetIdsBigInt);
35
+
65
36
  return {
66
37
  success: true,
67
38
  result: {
68
39
  transactionHash: result.hash,
69
40
  planetsAcquired: result.planetsAcquired,
70
- amountToMint: result.amountToMint,
71
- tokenAmount: result.tokenAmount,
41
+ costs: {
42
+ totalRequired: formatUnits(result.costs.totalRequired, 18),
43
+ playTokenUsed: formatUnits(result.costs.playTokenUsed, 18),
44
+ amountMinted: formatUnits(result.costs.amountMinted, 18),
45
+ },
72
46
  },
73
47
  };
74
48
  } catch (error) {
@@ -1,20 +1,33 @@
1
1
  import {z} from 'zod';
2
- import {createTool} from '../types.js';
2
+ import {createTool} from '../tool-handling/types.js';
3
+ import type {ConquestEnv} from '../types.js';
3
4
 
4
- export const exit_planets = createTool({
5
+ const schema = z.object({
6
+ coordinates: z
7
+ .array(
8
+ z.object({
9
+ x: z.number().describe('X coordinate of the planet'),
10
+ y: z.number().describe('Y coordinate of the planet'),
11
+ }),
12
+ )
13
+ .describe('Array of planet coordinates to exit'),
14
+ });
15
+
16
+ export const exit_planets = createTool<typeof schema, ConquestEnv>({
5
17
  description:
6
18
  'Exit (unstake) multiple planets to retrieve staked tokens. The exit process takes time and must be completed later.',
7
- schema: z.object({
8
- planetIds: z
9
- .array(z.union([z.string(), z.number()]))
10
- .describe('Array of planet location IDs to exit (as hex strings or numbers)'),
11
- }),
12
- execute: async (env, {planetIds}) => {
19
+ schema,
20
+ execute: async (env, {coordinates}) => {
13
21
  try {
14
- // Convert planet IDs to BigInt
15
- const planetIdsBigInt = planetIds.map((id) =>
16
- typeof id === 'string' ? BigInt(id) : BigInt(id),
17
- );
22
+ // Convert x,y coordinates to planet IDs
23
+ const planetIdsBigInt: bigint[] = [];
24
+ for (const coord of coordinates) {
25
+ const planetId = env.planetManager.getPlanetIdByCoordinates(coord.x, coord.y);
26
+ if (planetId === undefined) {
27
+ throw new Error(`No planet found at coordinates (${coord.x}, ${coord.y})`);
28
+ }
29
+ planetIdsBigInt.push(planetId);
30
+ }
18
31
 
19
32
  const result = await env.planetManager.exit(planetIdsBigInt);
20
33
 
@@ -0,0 +1,72 @@
1
+ import {z} from 'zod';
2
+ import {formatEther} from 'viem';
3
+ import {createTool} from '../tool-handling/types.js';
4
+ import type {ConquestEnv} from '../types.js';
5
+
6
+ const schema = z.object({
7
+ address: z
8
+ .string()
9
+ .optional()
10
+ .describe(
11
+ 'Address to check balance for. Defaults to current wallet if private key is available.',
12
+ ),
13
+ });
14
+
15
+ export const get_native_token_balance = createTool<typeof schema, ConquestEnv>({
16
+ description:
17
+ 'Get the native token (ETH) balance for an address. If no address provided, uses the current wallet address.',
18
+ schema,
19
+ execute: async (env, {address}) => {
20
+ try {
21
+ let targetAddress: `0x${string}`;
22
+
23
+ if (address) {
24
+ // Use provided address
25
+ if (!address.startsWith('0x') || address.length !== 42) {
26
+ return {
27
+ success: false,
28
+ error: 'Invalid address format. Must be a 42-character hex string starting with 0x.',
29
+ };
30
+ }
31
+ targetAddress = address as `0x${string}`;
32
+ } else {
33
+ // Use current wallet address
34
+ if (!env.clients.walletClient) {
35
+ return {
36
+ success: false,
37
+ error:
38
+ 'No address provided and no wallet client available. Please provide a PRIVATE_KEY environment variable or specify an address.',
39
+ };
40
+ }
41
+ const account = env.clients.walletClient.account;
42
+ if (!account) {
43
+ return {
44
+ success: false,
45
+ error: 'Wallet client has no account configured.',
46
+ };
47
+ }
48
+ targetAddress = account.address;
49
+ }
50
+
51
+ const balanceWei = await env.clients.publicClient.getBalance({
52
+ address: targetAddress,
53
+ });
54
+
55
+ const balanceEth = formatEther(balanceWei);
56
+
57
+ return {
58
+ success: true,
59
+ result: {
60
+ address: targetAddress,
61
+ balance: `${balanceEth} ETH`,
62
+ balanceWei: balanceWei.toString(),
63
+ },
64
+ };
65
+ } catch (error) {
66
+ return {
67
+ success: false,
68
+ error: error instanceof Error ? error.message : String(error),
69
+ };
70
+ }
71
+ },
72
+ });
@@ -1,11 +1,14 @@
1
1
  import {z} from 'zod';
2
- import {createTool} from '../types.js';
2
+ import {createTool} from '../tool-handling/types.js';
3
+ import type {ConquestEnv} from '../types.js';
3
4
 
4
- export const get_pending_exits = createTool({
5
+ const schema = z.object({
6
+ // No properties needed for this tool
7
+ });
8
+
9
+ export const get_pending_exits = createTool<typeof schema, ConquestEnv>({
5
10
  description: 'Get all pending exit (unstake) operations for your planets.',
6
- schema: z.object({
7
- // No properties needed for this tool
8
- }),
11
+ schema,
9
12
  execute: async (env) => {
10
13
  try {
11
14
  const exits = await env.planetManager.getMyPendingExits();
@@ -1,11 +1,14 @@
1
1
  import {z} from 'zod';
2
- import {createTool} from '../types.js';
2
+ import {createTool} from '../tool-handling/types.js';
3
+ import type {ConquestEnv} from '../types.js';
3
4
 
4
- export const get_pending_fleets = createTool({
5
+ const schema = z.object({
6
+ // No properties needed for this tool
7
+ });
8
+
9
+ export const get_pending_fleets = createTool<typeof schema, ConquestEnv>({
5
10
  description: 'Get all pending fleets sent from your planets.',
6
- schema: z.object({
7
- // No properties needed for this tool
8
- }),
11
+ schema,
9
12
  execute: async (env) => {
10
13
  try {
11
14
  const fleets = await env.fleetManager.getMyPendingFleets();
@@ -1,33 +1,62 @@
1
1
  import {z} from 'zod';
2
- import {createTool} from '../types.js';
2
+ import {createTool} from '../tool-handling/types.js';
3
+ import type {ConquestEnv} from '../types.js';
3
4
 
4
- export const get_planets_around = createTool({
5
+ const schema = z.object({
6
+ center: z.object({x: z.number(), y: z.number()}).describe('Center point coordinates {x, y}'),
7
+ radius: z
8
+ .number()
9
+ .min(1)
10
+ .max(50)
11
+ .describe('Radius in distance units to search around the center point (1-50)'),
12
+ only: z
13
+ .string()
14
+ .optional()
15
+ .describe('Filter by owner: use "me" for current wallet address, or provide an address'),
16
+ });
17
+
18
+ export const get_planets_around = createTool<typeof schema, ConquestEnv>({
5
19
  description:
6
- 'Get planets around a specific location within a certain radius. Useful for finding targets for fleet movement.',
7
- schema: z.object({
8
- centerX: z.number().describe('X coordinate of the center point'),
9
- centerY: z.number().describe('Y coordinate of the center point'),
10
- radius: z
11
- .number()
12
- .max(50)
13
- .describe('Radius in distance units to search around the center point'),
14
- }),
15
- execute: async (env, {centerX, centerY, radius}) => {
20
+ 'Get planets around a specific location within a certain radius. Useful for finding targets for fleet movement. Use the "only" parameter to filter by owner.',
21
+ schema,
22
+ execute: async (env, {center, radius, only}) => {
16
23
  try {
17
- const planets = await env.planetManager.getPlanetsAround(centerX, centerY, radius);
24
+ let planets = await env.planetManager.getPlanetsAround(center.x, center.y, radius);
25
+
26
+ // Filter by owner if 'only' parameter is provided
27
+ if (only) {
28
+ let filterAddress: string;
29
+ if (only.toLowerCase() === 'me') {
30
+ // Require wallet client for 'me' filter
31
+ const walletClient = env.clients.walletClient;
32
+ if (!walletClient?.account) {
33
+ return {
34
+ success: false,
35
+ error:
36
+ 'Wallet client with account required to use "me" filter. Private key must be set.',
37
+ };
38
+ }
39
+ filterAddress = walletClient.account.address.toLowerCase();
40
+ } else {
41
+ filterAddress = only.toLowerCase();
42
+ }
43
+
44
+ planets = planets.filter(({state}) => state.owner?.toLowerCase() === filterAddress);
45
+ }
18
46
 
19
47
  return {
20
48
  success: true,
21
49
  result: {
22
50
  center: {
23
- x: centerX,
24
- y: centerY,
51
+ x: center.x,
52
+ y: center.y,
25
53
  },
26
54
  radius,
55
+ ...(only && {filter: {only}}),
27
56
  planets: planets.map(({info, state}) => ({
28
57
  planetId: info.location.id,
29
58
  distance: Math.sqrt(
30
- Math.pow(info.location.x - centerX, 2) + Math.pow(info.location.y - centerY, 2),
59
+ Math.pow(info.location.x - center.x, 2) + Math.pow(info.location.y - center.y, 2),
31
60
  ),
32
61
  location: info.location,
33
62
  ...state,
@@ -0,0 +1,90 @@
1
+ import {z} from 'zod';
2
+ import {formatUnits} from 'viem';
3
+ import {createTool} from '../tool-handling/types.js';
4
+ import type {ConquestEnv} from '../types.js';
5
+
6
+ const schema = z.object({
7
+ address: z
8
+ .string()
9
+ .optional()
10
+ .describe(
11
+ 'Address to check balance for. Defaults to current wallet if private key is available.',
12
+ ),
13
+ });
14
+
15
+ // ERC20 balanceOf ABI
16
+ const erc20BalanceOfAbi = [
17
+ {
18
+ name: 'balanceOf',
19
+ type: 'function',
20
+ stateMutability: 'view',
21
+ inputs: [{name: 'account', type: 'address'}],
22
+ outputs: [{name: '', type: 'uint256'}],
23
+ },
24
+ ] as const;
25
+
26
+ export const get_play_token_balance = createTool<typeof schema, ConquestEnv>({
27
+ description:
28
+ 'Get the play token (staking token) balance for an address. If no address provided, uses the current wallet address.',
29
+ schema,
30
+ execute: async (env, {address}) => {
31
+ try {
32
+ let targetAddress: `0x${string}`;
33
+
34
+ if (address) {
35
+ // Use provided address
36
+ if (!address.startsWith('0x') || address.length !== 42) {
37
+ return {
38
+ success: false,
39
+ error: 'Invalid address format. Must be a 42-character hex string starting with 0x.',
40
+ };
41
+ }
42
+ targetAddress = address as `0x${string}`;
43
+ } else {
44
+ // Use current wallet address
45
+ if (!env.clients.walletClient) {
46
+ return {
47
+ success: false,
48
+ error:
49
+ 'No address provided and no wallet client available. Please provide a PRIVATE_KEY environment variable or specify an address.',
50
+ };
51
+ }
52
+ const account = env.clients.walletClient.account;
53
+ if (!account) {
54
+ return {
55
+ success: false,
56
+ error: 'Wallet client has no account configured.',
57
+ };
58
+ }
59
+ targetAddress = account.address;
60
+ }
61
+
62
+ const tokenAddress = env.contractConfig.stakingToken;
63
+
64
+ const balanceRaw = await env.clients.publicClient.readContract({
65
+ address: tokenAddress,
66
+ abi: erc20BalanceOfAbi,
67
+ functionName: 'balanceOf',
68
+ args: [targetAddress],
69
+ });
70
+
71
+ // Play tokens use 18 decimals
72
+ const balance = formatUnits(balanceRaw, 18);
73
+
74
+ return {
75
+ success: true,
76
+ result: {
77
+ address: targetAddress,
78
+ tokenAddress,
79
+ balance: `${balance} PLAY`,
80
+ balanceRaw: balanceRaw.toString(),
81
+ },
82
+ };
83
+ } catch (error) {
84
+ return {
85
+ success: false,
86
+ error: error instanceof Error ? error.message : String(error),
87
+ };
88
+ }
89
+ },
90
+ });
@@ -5,6 +5,12 @@ export {resolve_fleet} from './resolve_fleet.js';
5
5
  export {exit_planets} from './exit_planets.js';
6
6
  export {get_pending_exits} from './get_pending_exits.js';
7
7
  export {verify_exit_status} from './verify_exit_status.js';
8
- export {get_my_planets} from './get_my_planets.js';
9
8
  export {get_planets_around} from './get_planets_around.js';
10
9
  export {get_pending_fleets} from './get_pending_fleets.js';
10
+ export {get_native_token_balance} from './get_native_token_balance.js';
11
+ export {get_play_token_balance} from './get_play_token_balance.js';
12
+ export {withdraw} from './withdraw.js';
13
+ export {simulate} from './simulate.js';
14
+ export {simulate_multiple} from './simulate_multiple.js';
15
+ export {missiv_get_user} from './missiv_get_user.js';
16
+ export {missiv_register} from './missiv_register.js';