@dimcool/dimclaw 0.1.10 → 0.1.12

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.
package/dist/index.js CHANGED
@@ -55022,10 +55022,12 @@ var Wallet = class {
55022
55022
  */
55023
55023
  async getBalances() {
55024
55024
  try {
55025
- const response = await this.http.get(
55026
- "/wallets/me/balance"
55027
- );
55028
- return response;
55025
+ const raw = await this.http.get("/wallets/me/balance");
55026
+ const usdcDollars = raw.usdc / 1e6;
55027
+ return {
55028
+ ...raw,
55029
+ usdcFormatted: `$${usdcDollars.toFixed(2)}`
55030
+ };
55029
55031
  } catch (error) {
55030
55032
  this.logger.error("Failed to get balances", {
55031
55033
  error: error instanceof Error ? error.message : String(error)
@@ -57444,26 +57446,37 @@ function register(api) {
57444
57446
  }
57445
57447
  api.registerTool({
57446
57448
  name: "dim_login",
57447
- description: "Authenticate with DIM using the configured wallet. Must be called before using any other tools. Returns user profile info.",
57449
+ description: "Authenticate with DIM using the configured wallet. After login: set a username with dim_set_username, check balance with dim_get_balance, list games with dim_list_games, or apply a referral code with dim_apply_referral_code for a 10% fee discount.",
57448
57450
  parameters: { type: "object", properties: {}, additionalProperties: false },
57449
57451
  async execute() {
57450
57452
  const c = await requireClient();
57451
57453
  if ("error" in c) return c.error;
57452
57454
  try {
57453
57455
  const result = await c.authenticate();
57454
- const response = {
57455
- success: true,
57456
- userId: result.userId,
57457
- username: result.username,
57458
- walletAddress: c.walletAddress
57459
- };
57456
+ const nextSteps = [];
57457
+ if (result.username == null || result.username === "") {
57458
+ nextSteps.push(
57459
+ "No username set \u2014 call dim_set_username to claim one"
57460
+ );
57461
+ }
57462
+ nextSteps.push("Check your balance with dim_get_balance");
57463
+ nextSteps.push("Explore available games with dim_list_games");
57460
57464
  try {
57461
57465
  const summary = await c.sdk.referrals.getSummary();
57462
57466
  if (!summary.hasReferrer) {
57463
- response.referralHint = "You have no referrer yet. Use dim_apply_referral_code to apply one and get a 10% fee discount.";
57467
+ nextSteps.push(
57468
+ "No referrer yet \u2014 call dim_apply_referral_code for 10% fee discount"
57469
+ );
57464
57470
  }
57465
57471
  } catch {
57466
57472
  }
57473
+ const response = {
57474
+ success: true,
57475
+ userId: result.userId,
57476
+ username: result.username ?? null,
57477
+ walletAddress: c.walletAddress,
57478
+ nextSteps
57479
+ };
57467
57480
  return textResult(JSON.stringify(response, null, 2));
57468
57481
  } catch (err) {
57469
57482
  return textResult(
@@ -57529,9 +57542,165 @@ function register(api) {
57529
57542
  }
57530
57543
  }
57531
57544
  });
57545
+ const DIM_INSTRUCTIONS = [
57546
+ {
57547
+ name: "dim_login",
57548
+ description: "Authenticate with DIM. Call first; then set username, check balance, list games, or apply referral code."
57549
+ },
57550
+ {
57551
+ name: "dim_get_profile",
57552
+ description: "Get current user profile (username, avatar, bio, chess ELO)."
57553
+ },
57554
+ {
57555
+ name: "dim_set_username",
57556
+ description: "Set or update your username (alphanumeric, 3\u201320 chars)."
57557
+ },
57558
+ {
57559
+ name: "dim_list_instructions",
57560
+ description: "List all available DIM tools and short descriptions (this list)."
57561
+ },
57562
+ {
57563
+ name: "dim_get_balance",
57564
+ description: "Get SOL and USDC balance; usdcFormatted is always present (e.g. $0.00)."
57565
+ },
57566
+ {
57567
+ name: "dim_send_usdc",
57568
+ description: "Send USDC to a user by username or address. 1\xA2 fee; amount in dollars."
57569
+ },
57570
+ {
57571
+ name: "dim_tip_user",
57572
+ description: "Tip a user with USDC; broadcast to global chat. 1\xA2 fee."
57573
+ },
57574
+ {
57575
+ name: "dim_get_wallet_activity",
57576
+ description: "Get recent wallet activity (deposits, payouts, transfers)."
57577
+ },
57578
+ { name: "dim_search_users", description: "Search users by username." },
57579
+ {
57580
+ name: "dim_send_friend_request",
57581
+ description: "Send friend request by user ID."
57582
+ },
57583
+ {
57584
+ name: "dim_accept_friend_request",
57585
+ description: "Accept an incoming friend request."
57586
+ },
57587
+ {
57588
+ name: "dim_list_friends",
57589
+ description: "List your friends with pagination."
57590
+ },
57591
+ {
57592
+ name: "dim_get_incoming_friend_requests",
57593
+ description: "List pending incoming friend requests."
57594
+ },
57595
+ {
57596
+ name: "dim_send_message",
57597
+ description: "Send chat in a context (lobby, game, dm, global)."
57598
+ },
57599
+ {
57600
+ name: "dim_get_chat_history",
57601
+ description: "Get chat history for a context."
57602
+ },
57603
+ {
57604
+ name: "dim_send_dm",
57605
+ description: "Send a direct message to a user by ID."
57606
+ },
57607
+ {
57608
+ name: "dim_list_dm_threads",
57609
+ description: "List DM threads with last message and unread counts."
57610
+ },
57611
+ {
57612
+ name: "dim_list_games",
57613
+ description: "List available game types (RPS, Chess, Tic-Tac-Toe, etc.)."
57614
+ },
57615
+ {
57616
+ name: "dim_get_game_metrics",
57617
+ description: "Get real-time metrics: active players, live games, money in play."
57618
+ },
57619
+ {
57620
+ name: "dim_create_lobby",
57621
+ description: "Create a game lobby; bet in USDC dollars."
57622
+ },
57623
+ {
57624
+ name: "dim_join_queue",
57625
+ description: "Join matchmaking queue for a game type."
57626
+ },
57627
+ { name: "dim_get_lobby", description: "Get lobby details by ID." },
57628
+ {
57629
+ name: "dim_get_game_state",
57630
+ description: "Get current state of a game (for submitting moves)."
57631
+ },
57632
+ {
57633
+ name: "dim_submit_action",
57634
+ description: "Submit a move/action in a game."
57635
+ },
57636
+ { name: "dim_donate_to_pot", description: "Add to the pot in a lobby." },
57637
+ { name: "dim_get_game", description: "Get game summary by ID." },
57638
+ {
57639
+ name: "dim_challenge_user",
57640
+ description: "Challenge another user to a game."
57641
+ },
57642
+ { name: "dim_accept_challenge", description: "Accept a game challenge." },
57643
+ {
57644
+ name: "dim_get_referral_summary",
57645
+ description: "Get your referral stats and rewards."
57646
+ },
57647
+ { name: "dim_get_referral_tree", description: "Get your referral tree." },
57648
+ {
57649
+ name: "dim_get_referral_rewards",
57650
+ description: "Get claimable referral rewards."
57651
+ },
57652
+ {
57653
+ name: "dim_claim_referral_rewards",
57654
+ description: "Claim referral rewards to your wallet."
57655
+ },
57656
+ {
57657
+ name: "dim_apply_referral_code",
57658
+ description: "Apply a referral code for 10% fee discount."
57659
+ },
57660
+ {
57661
+ name: "dim_create_support_ticket",
57662
+ description: "Create a support ticket."
57663
+ },
57664
+ { name: "dim_get_my_tickets", description: "List your support tickets." },
57665
+ { name: "dim_get_ticket", description: "Get a ticket by ID." },
57666
+ {
57667
+ name: "dim_add_ticket_message",
57668
+ description: "Add a message to a ticket."
57669
+ },
57670
+ { name: "dim_close_ticket", description: "Close a support ticket." },
57671
+ {
57672
+ name: "dim_get_market",
57673
+ description: "Get prediction market for a game."
57674
+ },
57675
+ { name: "dim_buy_shares", description: "Buy prediction market shares." },
57676
+ { name: "dim_sell_shares", description: "Sell prediction market shares." },
57677
+ { name: "dim_get_positions", description: "Get your market positions." },
57678
+ {
57679
+ name: "dim_redeem_shares",
57680
+ description: "Redeem shares after market resolution."
57681
+ },
57682
+ { name: "dim_get_market_analytics", description: "Get market analytics." }
57683
+ ];
57684
+ api.registerTool({
57685
+ name: "dim_list_instructions",
57686
+ description: "List all available DIM tools (instructions) with short descriptions. Use this to discover what you can do after dim_login.",
57687
+ parameters: { type: "object", properties: {}, additionalProperties: false },
57688
+ async execute() {
57689
+ return textResult(
57690
+ JSON.stringify(
57691
+ {
57692
+ instructions: DIM_INSTRUCTIONS,
57693
+ hint: "Call dim_login first if you have not authenticated. Then use any tool above by name."
57694
+ },
57695
+ null,
57696
+ 2
57697
+ )
57698
+ );
57699
+ }
57700
+ });
57532
57701
  api.registerTool({
57533
57702
  name: "dim_get_balance",
57534
- description: "Get the wallet balance for the authenticated user. Returns SOL and USDC amounts. USDC amounts are in minor units (1 USDC = 1,000,000 minor units).",
57703
+ description: "Get the wallet balance for the authenticated user. Returns SOL and USDC (usdc in minor units; usdcFormatted is always present, e.g. $0.00 or $1.50, so you do not need to convert).",
57535
57704
  parameters: { type: "object", properties: {}, additionalProperties: false },
57536
57705
  async execute() {
57537
57706
  const c = await requireClient();
@@ -57539,13 +57708,11 @@ function register(api) {
57539
57708
  try {
57540
57709
  const balance = await c.sdk.wallet.getBalances();
57541
57710
  const usdcDollars = balance.usdc / 1e6;
57542
- return textResult(
57543
- JSON.stringify(
57544
- { ...balance, usdcFormatted: `$${usdcDollars.toFixed(2)}` },
57545
- null,
57546
- 2
57547
- )
57548
- );
57711
+ const payload = {
57712
+ ...balance,
57713
+ usdcFormatted: `$${usdcDollars.toFixed(2)}`
57714
+ };
57715
+ return textResult(JSON.stringify(payload, null, 2));
57549
57716
  } catch (err) {
57550
57717
  return textResult(
57551
57718
  `Failed to get balance: ${err instanceof Error ? err.message : String(err)}`,
@@ -57997,17 +58164,17 @@ function register(api) {
57997
58164
  });
57998
58165
  api.registerTool({
57999
58166
  name: "dim_create_lobby",
58000
- description: "Create a new game lobby. The agent becomes the lobby creator. Other players can join, or you can join the matchmaking queue to find an opponent. Bet amount is in USDC minor units (1 USDC = 1,000,000). A 1% fee (min 1 cent) is charged per player.",
58167
+ description: "Create a new game lobby. The agent becomes the lobby creator. Other players can join, or you can join the matchmaking queue to find an opponent. Bet amount is in USDC dollars (e.g., 1.00 for $1.00). A 1% fee (min 1 cent) is charged per player.",
58001
58168
  parameters: {
58002
58169
  type: "object",
58003
58170
  properties: {
58004
58171
  gameType: {
58005
58172
  type: "string",
58006
- description: 'Game type ID (e.g., "rock-paper-scissors", "chess", "tic-tac-toe", "connect-four", "nim", "dots-and-boxes")'
58173
+ description: 'Game type ID (e.g., "rock-paper-scissors", "chess", "tic-tac-toe", "connect-four")'
58007
58174
  },
58008
58175
  betAmount: {
58009
58176
  type: "number",
58010
- description: "Bet amount in USDC minor units (e.g., 1000000 = $1.00). Common amounts: 1000000 ($1), 5000000 ($5), 10000000 ($10)"
58177
+ description: "Bet amount in USDC dollars (e.g., 1.00 for $1.00, 5.00 for $5.00, 10.00 for $10.00)"
58011
58178
  }
58012
58179
  },
58013
58180
  required: ["gameType"],
@@ -58017,7 +58184,7 @@ function register(api) {
58017
58184
  const c = await requireClient();
58018
58185
  if ("error" in c) return c.error;
58019
58186
  const gameType = String(params.gameType ?? "");
58020
- const betAmount = typeof params.betAmount === "number" ? params.betAmount : void 0;
58187
+ const betAmount = typeof params.betAmount === "number" ? Math.round(params.betAmount * 1e6) : void 0;
58021
58188
  try {
58022
58189
  const lobby = await c.sdk.lobbies.createLobby(gameType, betAmount);
58023
58190
  return textResult(
@@ -58144,7 +58311,7 @@ function register(api) {
58144
58311
  });
58145
58312
  api.registerTool({
58146
58313
  name: "dim_submit_action",
58147
- description: 'Submit a game action. The action format depends on the game type.\n\nRock-Paper-Scissors: gameType="rock-paper-scissors", action="play", payload={ action: "rock"|"paper"|"scissors" }\nChess: gameType="chess", action="move", payload={ from: "e2", to: "e4" }\nTic-Tac-Toe: gameType="tic-tac-toe", action="place", payload={ position: 0-8 }\nConnect Four: gameType="connect-four", action="drop", payload={ column: 0-6 }\nNim: gameType="nim", action="take", payload={ heap: 0-2, count: 1-N }\nDots and Boxes: gameType="dots-and-boxes", action="draw", payload={ row, col, direction: "h"|"v" }',
58314
+ description: 'Submit a game action. The action format depends on the game type.\n\nRock-Paper-Scissors: gameType="rock-paper-scissors", action="play", payload={ action: "rock"|"paper"|"scissors" }\nChess: gameType="chess", action="move", payload={ from: "e2", to: "e4" }\nTic-Tac-Toe: gameType="tic-tac-toe", action="place_mark", payload={ row: 0-2, col: 0-2 }\nConnect Four: gameType="connect-four", action="drop_disc", payload={ column: 0-6 }',
58148
58315
  parameters: {
58149
58316
  type: "object",
58150
58317
  properties: {
@@ -58154,11 +58321,11 @@ function register(api) {
58154
58321
  },
58155
58322
  gameType: {
58156
58323
  type: "string",
58157
- description: 'Game type (e.g., "rock-paper-scissors", "chess", "tic-tac-toe")'
58324
+ description: 'Game type (e.g., "rock-paper-scissors", "chess", "tic-tac-toe", "connect-four")'
58158
58325
  },
58159
58326
  action: {
58160
58327
  type: "string",
58161
- description: 'Action type (e.g., "play", "move", "place", "drop")'
58328
+ description: 'Action type (e.g., "play", "move", "place_mark", "drop_disc")'
58162
58329
  },
58163
58330
  payload: {
58164
58331
  type: "object",
@@ -58172,11 +58339,12 @@ function register(api) {
58172
58339
  const c = await requireClient();
58173
58340
  if ("error" in c) return c.error;
58174
58341
  try {
58175
- await c.sdk.games.submitAction(String(params.gameId ?? ""), {
58342
+ const gameAction = {
58176
58343
  gameType: String(params.gameType ?? ""),
58177
58344
  action: String(params.action ?? ""),
58178
58345
  payload: params.payload ?? {}
58179
- });
58346
+ };
58347
+ await c.sdk.games.submitAction(String(params.gameId ?? ""), gameAction);
58180
58348
  return textResult(
58181
58349
  JSON.stringify(
58182
58350
  {
package/index.ts CHANGED
@@ -7,6 +7,7 @@ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
7
7
  import path from 'node:path';
8
8
  import { Keypair, Transaction } from '@solana/web3.js';
9
9
  import bs58 from 'bs58';
10
+ import type { ValidAction } from '@dimcool/sdk';
10
11
  import { DimClient } from './dim-client';
11
12
 
12
13
  type PluginConfig = {
@@ -149,28 +150,38 @@ export default function register(api: {
149
150
  api.registerTool({
150
151
  name: 'dim_login',
151
152
  description:
152
- 'Authenticate with DIM using the configured wallet. Must be called before using any other tools. Returns user profile info.',
153
+ 'Authenticate with DIM using the configured wallet. After login: set a username with dim_set_username, check balance with dim_get_balance, list games with dim_list_games, or apply a referral code with dim_apply_referral_code for a 10% fee discount.',
153
154
  parameters: { type: 'object', properties: {}, additionalProperties: false },
154
155
  async execute() {
155
156
  const c = await requireClient();
156
157
  if ('error' in c) return c.error;
157
158
  try {
158
159
  const result = await c.authenticate();
159
- const response: Record<string, unknown> = {
160
- success: true,
161
- userId: result.userId,
162
- username: result.username,
163
- walletAddress: c.walletAddress,
164
- };
160
+ const nextSteps: string[] = [];
161
+ if (result.username == null || result.username === '') {
162
+ nextSteps.push(
163
+ 'No username set — call dim_set_username to claim one',
164
+ );
165
+ }
166
+ nextSteps.push('Check your balance with dim_get_balance');
167
+ nextSteps.push('Explore available games with dim_list_games');
165
168
  try {
166
169
  const summary = await c.sdk.referrals.getSummary();
167
170
  if (!summary.hasReferrer) {
168
- response.referralHint =
169
- 'You have no referrer yet. Use dim_apply_referral_code to apply one and get a 10% fee discount.';
171
+ nextSteps.push(
172
+ 'No referrer yet call dim_apply_referral_code for 10% fee discount',
173
+ );
170
174
  }
171
175
  } catch {
172
176
  /* non-critical */
173
177
  }
178
+ const response: Record<string, unknown> = {
179
+ success: true,
180
+ userId: result.userId,
181
+ username: result.username ?? null,
182
+ walletAddress: c.walletAddress,
183
+ nextSteps,
184
+ };
174
185
  return textResult(JSON.stringify(response, null, 2));
175
186
  } catch (err) {
176
187
  return textResult(
@@ -242,11 +253,176 @@ export default function register(api: {
242
253
  },
243
254
  });
244
255
 
256
+ // --- Instructions (discovery) ---
257
+ const DIM_INSTRUCTIONS = [
258
+ {
259
+ name: 'dim_login',
260
+ description:
261
+ 'Authenticate with DIM. Call first; then set username, check balance, list games, or apply referral code.',
262
+ },
263
+ {
264
+ name: 'dim_get_profile',
265
+ description:
266
+ 'Get current user profile (username, avatar, bio, chess ELO).',
267
+ },
268
+ {
269
+ name: 'dim_set_username',
270
+ description: 'Set or update your username (alphanumeric, 3–20 chars).',
271
+ },
272
+ {
273
+ name: 'dim_list_instructions',
274
+ description:
275
+ 'List all available DIM tools and short descriptions (this list).',
276
+ },
277
+ {
278
+ name: 'dim_get_balance',
279
+ description:
280
+ 'Get SOL and USDC balance; usdcFormatted is always present (e.g. $0.00).',
281
+ },
282
+ {
283
+ name: 'dim_send_usdc',
284
+ description:
285
+ 'Send USDC to a user by username or address. 1¢ fee; amount in dollars.',
286
+ },
287
+ {
288
+ name: 'dim_tip_user',
289
+ description: 'Tip a user with USDC; broadcast to global chat. 1¢ fee.',
290
+ },
291
+ {
292
+ name: 'dim_get_wallet_activity',
293
+ description: 'Get recent wallet activity (deposits, payouts, transfers).',
294
+ },
295
+ { name: 'dim_search_users', description: 'Search users by username.' },
296
+ {
297
+ name: 'dim_send_friend_request',
298
+ description: 'Send friend request by user ID.',
299
+ },
300
+ {
301
+ name: 'dim_accept_friend_request',
302
+ description: 'Accept an incoming friend request.',
303
+ },
304
+ {
305
+ name: 'dim_list_friends',
306
+ description: 'List your friends with pagination.',
307
+ },
308
+ {
309
+ name: 'dim_get_incoming_friend_requests',
310
+ description: 'List pending incoming friend requests.',
311
+ },
312
+ {
313
+ name: 'dim_send_message',
314
+ description: 'Send chat in a context (lobby, game, dm, global).',
315
+ },
316
+ {
317
+ name: 'dim_get_chat_history',
318
+ description: 'Get chat history for a context.',
319
+ },
320
+ {
321
+ name: 'dim_send_dm',
322
+ description: 'Send a direct message to a user by ID.',
323
+ },
324
+ {
325
+ name: 'dim_list_dm_threads',
326
+ description: 'List DM threads with last message and unread counts.',
327
+ },
328
+ {
329
+ name: 'dim_list_games',
330
+ description: 'List available game types (RPS, Chess, Tic-Tac-Toe, etc.).',
331
+ },
332
+ {
333
+ name: 'dim_get_game_metrics',
334
+ description:
335
+ 'Get real-time metrics: active players, live games, money in play.',
336
+ },
337
+ {
338
+ name: 'dim_create_lobby',
339
+ description: 'Create a game lobby; bet in USDC dollars.',
340
+ },
341
+ {
342
+ name: 'dim_join_queue',
343
+ description: 'Join matchmaking queue for a game type.',
344
+ },
345
+ { name: 'dim_get_lobby', description: 'Get lobby details by ID.' },
346
+ {
347
+ name: 'dim_get_game_state',
348
+ description: 'Get current state of a game (for submitting moves).',
349
+ },
350
+ {
351
+ name: 'dim_submit_action',
352
+ description: 'Submit a move/action in a game.',
353
+ },
354
+ { name: 'dim_donate_to_pot', description: 'Add to the pot in a lobby.' },
355
+ { name: 'dim_get_game', description: 'Get game summary by ID.' },
356
+ {
357
+ name: 'dim_challenge_user',
358
+ description: 'Challenge another user to a game.',
359
+ },
360
+ { name: 'dim_accept_challenge', description: 'Accept a game challenge.' },
361
+ {
362
+ name: 'dim_get_referral_summary',
363
+ description: 'Get your referral stats and rewards.',
364
+ },
365
+ { name: 'dim_get_referral_tree', description: 'Get your referral tree.' },
366
+ {
367
+ name: 'dim_get_referral_rewards',
368
+ description: 'Get claimable referral rewards.',
369
+ },
370
+ {
371
+ name: 'dim_claim_referral_rewards',
372
+ description: 'Claim referral rewards to your wallet.',
373
+ },
374
+ {
375
+ name: 'dim_apply_referral_code',
376
+ description: 'Apply a referral code for 10% fee discount.',
377
+ },
378
+ {
379
+ name: 'dim_create_support_ticket',
380
+ description: 'Create a support ticket.',
381
+ },
382
+ { name: 'dim_get_my_tickets', description: 'List your support tickets.' },
383
+ { name: 'dim_get_ticket', description: 'Get a ticket by ID.' },
384
+ {
385
+ name: 'dim_add_ticket_message',
386
+ description: 'Add a message to a ticket.',
387
+ },
388
+ { name: 'dim_close_ticket', description: 'Close a support ticket.' },
389
+ {
390
+ name: 'dim_get_market',
391
+ description: 'Get prediction market for a game.',
392
+ },
393
+ { name: 'dim_buy_shares', description: 'Buy prediction market shares.' },
394
+ { name: 'dim_sell_shares', description: 'Sell prediction market shares.' },
395
+ { name: 'dim_get_positions', description: 'Get your market positions.' },
396
+ {
397
+ name: 'dim_redeem_shares',
398
+ description: 'Redeem shares after market resolution.',
399
+ },
400
+ { name: 'dim_get_market_analytics', description: 'Get market analytics.' },
401
+ ];
402
+ api.registerTool({
403
+ name: 'dim_list_instructions',
404
+ description:
405
+ 'List all available DIM tools (instructions) with short descriptions. Use this to discover what you can do after dim_login.',
406
+ parameters: { type: 'object', properties: {}, additionalProperties: false },
407
+ async execute() {
408
+ return textResult(
409
+ JSON.stringify(
410
+ {
411
+ instructions: DIM_INSTRUCTIONS,
412
+ hint: 'Call dim_login first if you have not authenticated. Then use any tool above by name.',
413
+ },
414
+ null,
415
+ 2,
416
+ ),
417
+ );
418
+ },
419
+ });
420
+
245
421
  // --- Wallet ---
246
422
  api.registerTool({
247
423
  name: 'dim_get_balance',
248
424
  description:
249
- 'Get the wallet balance for the authenticated user. Returns SOL and USDC amounts. USDC amounts are in minor units (1 USDC = 1,000,000 minor units).',
425
+ 'Get the wallet balance for the authenticated user. Returns SOL and USDC (usdc in minor units; usdcFormatted is always present, e.g. $0.00 or $1.50, so you do not need to convert).',
250
426
  parameters: { type: 'object', properties: {}, additionalProperties: false },
251
427
  async execute() {
252
428
  const c = await requireClient();
@@ -254,13 +430,11 @@ export default function register(api: {
254
430
  try {
255
431
  const balance = await c.sdk.wallet.getBalances();
256
432
  const usdcDollars = balance.usdc / 1_000_000;
257
- return textResult(
258
- JSON.stringify(
259
- { ...balance, usdcFormatted: `$${usdcDollars.toFixed(2)}` },
260
- null,
261
- 2,
262
- ),
263
- );
433
+ const payload = {
434
+ ...balance,
435
+ usdcFormatted: `$${usdcDollars.toFixed(2)}`,
436
+ };
437
+ return textResult(JSON.stringify(payload, null, 2));
264
438
  } catch (err) {
265
439
  return textResult(
266
440
  `Failed to get balance: ${err instanceof Error ? err.message : String(err)}`,
@@ -743,19 +917,19 @@ export default function register(api: {
743
917
  api.registerTool({
744
918
  name: 'dim_create_lobby',
745
919
  description:
746
- 'Create a new game lobby. The agent becomes the lobby creator. Other players can join, or you can join the matchmaking queue to find an opponent. Bet amount is in USDC minor units (1 USDC = 1,000,000). A 1% fee (min 1 cent) is charged per player.',
920
+ 'Create a new game lobby. The agent becomes the lobby creator. Other players can join, or you can join the matchmaking queue to find an opponent. Bet amount is in USDC dollars (e.g., 1.00 for $1.00). A 1% fee (min 1 cent) is charged per player.',
747
921
  parameters: {
748
922
  type: 'object',
749
923
  properties: {
750
924
  gameType: {
751
925
  type: 'string',
752
926
  description:
753
- 'Game type ID (e.g., "rock-paper-scissors", "chess", "tic-tac-toe", "connect-four", "nim", "dots-and-boxes")',
927
+ 'Game type ID (e.g., "rock-paper-scissors", "chess", "tic-tac-toe", "connect-four")',
754
928
  },
755
929
  betAmount: {
756
930
  type: 'number',
757
931
  description:
758
- 'Bet amount in USDC minor units (e.g., 1000000 = $1.00). Common amounts: 1000000 ($1), 5000000 ($5), 10000000 ($10)',
932
+ 'Bet amount in USDC dollars (e.g., 1.00 for $1.00, 5.00 for $5.00, 10.00 for $10.00)',
759
933
  },
760
934
  },
761
935
  required: ['gameType'],
@@ -766,7 +940,9 @@ export default function register(api: {
766
940
  if ('error' in c) return c.error;
767
941
  const gameType = String(params.gameType ?? '');
768
942
  const betAmount =
769
- typeof params.betAmount === 'number' ? params.betAmount : undefined;
943
+ typeof params.betAmount === 'number'
944
+ ? Math.round(params.betAmount * 1_000_000)
945
+ : undefined;
770
946
  try {
771
947
  const lobby = await c.sdk.lobbies.createLobby(gameType, betAmount);
772
948
  return textResult(
@@ -908,10 +1084,8 @@ export default function register(api: {
908
1084
  'Submit a game action. The action format depends on the game type.\n\n' +
909
1085
  'Rock-Paper-Scissors: gameType="rock-paper-scissors", action="play", payload={ action: "rock"|"paper"|"scissors" }\n' +
910
1086
  'Chess: gameType="chess", action="move", payload={ from: "e2", to: "e4" }\n' +
911
- 'Tic-Tac-Toe: gameType="tic-tac-toe", action="place", payload={ position: 0-8 }\n' +
912
- 'Connect Four: gameType="connect-four", action="drop", payload={ column: 0-6 }\n' +
913
- 'Nim: gameType="nim", action="take", payload={ heap: 0-2, count: 1-N }\n' +
914
- 'Dots and Boxes: gameType="dots-and-boxes", action="draw", payload={ row, col, direction: "h"|"v" }',
1087
+ 'Tic-Tac-Toe: gameType="tic-tac-toe", action="place_mark", payload={ row: 0-2, col: 0-2 }\n' +
1088
+ 'Connect Four: gameType="connect-four", action="drop_disc", payload={ column: 0-6 }',
915
1089
  parameters: {
916
1090
  type: 'object',
917
1091
  properties: {
@@ -922,11 +1096,12 @@ export default function register(api: {
922
1096
  gameType: {
923
1097
  type: 'string',
924
1098
  description:
925
- 'Game type (e.g., "rock-paper-scissors", "chess", "tic-tac-toe")',
1099
+ 'Game type (e.g., "rock-paper-scissors", "chess", "tic-tac-toe", "connect-four")',
926
1100
  },
927
1101
  action: {
928
1102
  type: 'string',
929
- description: 'Action type (e.g., "play", "move", "place", "drop")',
1103
+ description:
1104
+ 'Action type (e.g., "play", "move", "place_mark", "drop_disc")',
930
1105
  },
931
1106
  payload: {
932
1107
  type: 'object',
@@ -941,11 +1116,12 @@ export default function register(api: {
941
1116
  const c = await requireClient();
942
1117
  if ('error' in c) return c.error;
943
1118
  try {
944
- await c.sdk.games.submitAction(String(params.gameId ?? ''), {
1119
+ const gameAction = {
945
1120
  gameType: String(params.gameType ?? ''),
946
1121
  action: String(params.action ?? ''),
947
1122
  payload: (params.payload as Record<string, unknown>) ?? {},
948
- } as never);
1123
+ } as ValidAction;
1124
+ await c.sdk.games.submitAction(String(params.gameId ?? ''), gameAction);
949
1125
  return textResult(
950
1126
  JSON.stringify(
951
1127
  {
@@ -30,5 +30,7 @@
30
30
  "label": "API URL",
31
31
  "placeholder": "https://api.dim.cool"
32
32
  }
33
- }
33
+ },
34
+ "setupHint": "After install, add your Solana wallet private key to plugins.entries.dimclaw.config.walletPrivateKey, then call dim_login to get started.",
35
+ "skill": "./SKILL.md"
34
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimcool/dimclaw",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "OpenClaw plugin for DIM — play games, chat, send USDC, and earn on DIM using the SDK directly (no MCP subprocess).",
5
5
  "type": "module",
6
6
  "openclaw": {