@agentlayer.tech/wallet 0.1.24 → 0.1.25

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.
@@ -118,8 +118,8 @@ The intended user-facing flow inside OpenClaw is:
118
118
  transfers, swaps, Aave position changes, staking, stake deactivation, and stake withdrawals should start in `preview`.
119
119
  3. Prepare only with intent:
120
120
  `prepare` is for explicit execution planning intent and returns no signed transaction bytes.
121
- 4. Execute only with approval:
122
- `execute` requires a host-issued `approval_token` bound to the exact previewed operation. On `mainnet`, that token must include explicit mainnet confirmation.
121
+ 4. Execute only after chat confirmation:
122
+ after the user explicitly confirms the shown preview/prepare summary in chat, call `execute` with the same semantic params. The OpenClaw extension handles the internal execution authorization automatically and binds it to the cached operation.
123
123
  5. On mainnet, restate the network, asset, amount, and destination, validator, or stake account before execute.
124
124
 
125
125
  For staking specifically, the normal agent flow should be:
@@ -25,6 +25,10 @@ const approvalPreviewCache = new Map();
25
25
  const privateSwapOrderCache = new Map();
26
26
  const WALLET_TOOL_ONLY_GUIDANCE =
27
27
  "Use this wallet tool instead of shelling out to solana CLI, spl-token CLI, curl, or exec. If it fails, surface the wallet-tool error and stop rather than falling back to terminal commands.";
28
+ const OPENCLAW_EXECUTE_APPROVAL_GUIDANCE =
29
+ "Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute with the same semantic params; the OpenClaw plugin handles the internal execution authorization automatically.";
30
+ const APPROVAL_CONTEXT_MISSING_MESSAGE =
31
+ `Confirmation context is not ready or expired. ${OPENCLAW_EXECUTE_APPROVAL_GUIDANCE} Do not ask for /approve, buttons, popups, or a manual token.`;
28
32
  const APPROVAL_PREVIEW_TOOL_ALIASES = new Map([
29
33
  ["x402_pay_request", "x402_preview_request"],
30
34
  ]);
@@ -71,19 +75,19 @@ function pruneApprovalPreviewCache() {
71
75
  function cachePreviewForApproval(userId, toolName, payload) {
72
76
  const cacheToolName = approvalPreviewToolName(toolName);
73
77
  if (!payload || payload.ok !== true || !payload.data || typeof payload.data !== "object") return;
74
- const preview = payload.data;
75
- if (preview.mode !== "preview") return;
76
- if (!preview.confirmation_summary || typeof preview.confirmation_summary !== "object") return;
78
+ const approvalSource = payload.data;
79
+ if (!["preview", "prepare"].includes(String(approvalSource.mode || ""))) return;
80
+ if (!approvalSource.confirmation_summary || typeof approvalSource.confirmation_summary !== "object") return;
77
81
  pruneApprovalPreviewCache();
78
- const digest = previewDigest(preview);
82
+ const digest = previewDigest(approvalSource);
79
83
  approvalPreviewCache.set(approvalCacheKey(userId, cacheToolName), {
80
84
  digest,
81
85
  expiresAt:
82
86
  cacheToolName === "swap_solana_privately"
83
87
  ? Date.now() + PRIVATE_SWAP_CACHE_TTL_MS
84
88
  : Date.now() + PREVIEW_CACHE_TTL_MS,
85
- preview,
86
- summary: preview.confirmation_summary,
89
+ preview: approvalSource,
90
+ summary: approvalSource.confirmation_summary,
87
91
  });
88
92
  if (cacheToolName === "swap_solana_privately") {
89
93
  privateSwapOrderCache.delete(approvalCacheKey(userId, cacheToolName));
@@ -115,6 +119,31 @@ function cachedPreviewForToken(userId, toolName, token) {
115
119
  return cached.preview && typeof cached.preview === "object" ? cached.preview : null;
116
120
  }
117
121
 
122
+ function requiresApprovedPreviewPayload(toolName) {
123
+ return PREVIEW_BOUND_SWAP_TOOLS.has(toolName);
124
+ }
125
+
126
+ function looksLikeApprovalContextError(message) {
127
+ const text = String(message || "").toLowerCase();
128
+ return (
129
+ text.includes("approval_token") ||
130
+ text.includes("approval token") ||
131
+ text.includes("approval context") ||
132
+ text.includes("approved preview") ||
133
+ text.includes("preview payload") ||
134
+ text.includes("previewed operation")
135
+ );
136
+ }
137
+
138
+ function normalizeApprovalContextError(error) {
139
+ const message = String(error?.message || error || "");
140
+ if (!looksLikeApprovalContextError(message)) return error;
141
+ const wrapped = new Error(`${APPROVAL_CONTEXT_MISSING_MESSAGE} Original wallet error: ${message}`);
142
+ if (typeof error?.code === "string") wrapped.code = error.code;
143
+ if (error?.details && typeof error.details === "object") wrapped.details = error.details;
144
+ return wrapped;
145
+ }
146
+
118
147
  function cachePendingPrivateSwapOrder(userId, toolName, preview, details) {
119
148
  if (toolName !== "swap_solana_privately") return;
120
149
  if (!preview || typeof preview !== "object") return;
@@ -530,6 +559,41 @@ async function issueApprovalToken(api, config, userId, toolName, previewPayload)
530
559
  return token;
531
560
  }
532
561
 
562
+ async function attachApprovalForExecute(api, config, userId, toolName, effectiveParams) {
563
+ if (String(effectiveParams.mode || "") !== "execute") return null;
564
+
565
+ const cached = latestCachedPreview(userId, toolName);
566
+ if (cached?.preview && cached?.summary) {
567
+ effectiveParams.approval_token = await issueApprovalToken(
568
+ api,
569
+ config,
570
+ userId,
571
+ toolName,
572
+ cached.preview
573
+ );
574
+ if (requiresApprovedPreviewPayload(toolName)) {
575
+ effectiveParams._approved_preview = cached.preview;
576
+ }
577
+ return cached;
578
+ }
579
+
580
+ if (
581
+ requiresApprovedPreviewPayload(toolName) &&
582
+ typeof effectiveParams.approval_token === "string" &&
583
+ effectiveParams.approval_token.trim() &&
584
+ effectiveParams._approved_preview === undefined
585
+ ) {
586
+ const cachedPreview = cachedPreviewForToken(userId, toolName, effectiveParams.approval_token);
587
+ if (cachedPreview) {
588
+ effectiveParams._approved_preview = cachedPreview;
589
+ }
590
+ }
591
+
592
+ if (effectiveParams.approval_token) return null;
593
+
594
+ throw new Error(APPROVAL_CONTEXT_MISSING_MESSAGE);
595
+ }
596
+
533
597
  function asContent(data) {
534
598
  return {
535
599
  content: [
@@ -664,40 +728,15 @@ function registerTool(api, definition) {
664
728
  if (activeBackend === "wdk_evm_local" && effectiveParams.network !== undefined) {
665
729
  configOverride.network = normalizeSelectableEvmNetwork(effectiveParams.network);
666
730
  }
667
- if (String(effectiveParams.mode || "") === "execute") {
668
- if (
669
- PREVIEW_BOUND_SWAP_TOOLS.has(definition.name) &&
670
- typeof effectiveParams.approval_token === "string" &&
671
- effectiveParams.approval_token.trim() &&
672
- effectiveParams._approved_preview === undefined
673
- ) {
674
- const cachedPreview = cachedPreviewForToken(userId, definition.name, effectiveParams.approval_token);
675
- if (cachedPreview) {
676
- effectiveParams._approved_preview = cachedPreview;
677
- }
678
- }
679
- if (!effectiveParams.approval_token) {
680
- const cached = latestCachedPreview(userId, definition.name);
681
- if (cached?.preview && cached?.summary) {
682
- effectiveParams.approval_token = await issueApprovalToken(
683
- api,
684
- configOverride,
685
- userId,
686
- definition.name,
687
- cached.preview
688
- );
689
- if (PREVIEW_BOUND_SWAP_TOOLS.has(definition.name) && effectiveParams._approved_preview === undefined) {
690
- effectiveParams._approved_preview = cached.preview;
691
- }
692
- }
693
- }
731
+ if (definition.name !== "continue_solana_private_swap") {
732
+ await attachApprovalForExecute(api, configOverride, userId, definition.name, effectiveParams);
694
733
  }
695
734
  if (definition.name === "continue_solana_private_swap") {
696
735
  const cached = latestCachedPreview(userId, PRIVATE_SWAP_APPROVAL_TOOL_NAME);
697
- if (cached?.preview && effectiveParams._approved_preview === undefined) {
736
+ if (cached?.preview) {
698
737
  effectiveParams._approved_preview = cached.preview;
699
738
  }
700
- if (!effectiveParams.approval_token && cached?.preview && cached?.summary) {
739
+ if (cached?.preview && cached?.summary) {
701
740
  effectiveParams.approval_token = await issueApprovalToken(
702
741
  api,
703
742
  configOverride,
@@ -705,6 +744,8 @@ function registerTool(api, definition) {
705
744
  PRIVATE_SWAP_APPROVAL_TOOL_NAME,
706
745
  cached.preview
707
746
  );
747
+ } else if (!effectiveParams.approval_token) {
748
+ throw new Error(APPROVAL_CONTEXT_MISSING_MESSAGE);
708
749
  }
709
750
  if (effectiveParams._resume_private_swap_order === undefined && cached?.preview) {
710
751
  const pendingOrder = latestPendingPrivateSwapOrder(
@@ -784,16 +825,24 @@ function registerTool(api, definition) {
784
825
  if (errorCode === "houdini_exchange_rate_limited" && errorDetails) {
785
826
  throw new Error(formatPrivateSwapRateLimitError(errorDetails));
786
827
  }
787
- throw error;
828
+ throw normalizeApprovalContextError(error);
788
829
  }
789
830
  }
790
831
  } else if (definition.name === "continue_solana_private_swap") {
791
- payload = await executeWalletTool();
832
+ try {
833
+ payload = await executeWalletTool();
834
+ } catch (error) {
835
+ throw normalizeApprovalContextError(error);
836
+ }
792
837
  if (payload?.data?.execution_state === "funding_submitted") {
793
838
  clearPendingPrivateSwapOrder(userId, PRIVATE_SWAP_APPROVAL_TOOL_NAME);
794
839
  }
795
840
  } else {
796
- payload = await executeWalletTool();
841
+ try {
842
+ payload = await executeWalletTool();
843
+ } catch (error) {
844
+ throw normalizeApprovalContextError(error);
845
+ }
797
846
  }
798
847
  cachePreviewForApproval(userId, definition.name, payload);
799
848
  if (payload?.ok === false) {
@@ -888,7 +937,7 @@ const walletSessionToolDefinitions = [
888
937
  {
889
938
  name: "x402_pay_request",
890
939
  description:
891
- "Prepare or execute an x402 paid request using the active wallet backend. This milestone executes the Solana exact buyer flow and keeps EVM as prepare-only.",
940
+ `Prepare or execute an x402 paid request using the active wallet backend. This milestone executes the Solana exact buyer flow and keeps EVM as prepare-only. ${OPENCLAW_EXECUTE_APPROVAL_GUIDANCE}`,
892
941
  parameters: {
893
942
  type: "object",
894
943
  properties: {
@@ -908,10 +957,6 @@ const walletSessionToolDefinitions = [
908
957
  type: "boolean",
909
958
  description: "Must be true for prepare mode.",
910
959
  },
911
- approval_token: {
912
- type: "string",
913
- description: "Required for execute mode and must be issued against the exact x402 payment summary.",
914
- },
915
960
  },
916
961
  required: ["url", "mode", "purpose"],
917
962
  additionalProperties: false,
@@ -1216,7 +1261,7 @@ const solanaToolDefinitions = [
1216
1261
  },
1217
1262
  {
1218
1263
  name: "sign_wallet_message",
1219
- description: "Sign an arbitrary message with the connected wallet after explicit approval.",
1264
+ description: "Sign an arbitrary message with the connected wallet after explicit user confirmation in chat.",
1220
1265
  optional: true,
1221
1266
  parameters: {
1222
1267
  type: "object",
@@ -1231,7 +1276,7 @@ const solanaToolDefinitions = [
1231
1276
  },
1232
1277
  {
1233
1278
  name: "transfer_sol",
1234
- description: "Preview, prepare, or execute a native SOL transfer. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1279
+ description: "Preview, prepare, or execute a native SOL transfer. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1235
1280
  optional: true,
1236
1281
  parameters: {
1237
1282
  type: "object",
@@ -1241,7 +1286,6 @@ const solanaToolDefinitions = [
1241
1286
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1242
1287
  purpose: { type: "string" },
1243
1288
  user_intent: { type: "boolean" },
1244
- approval_token: { type: "string" },
1245
1289
  },
1246
1290
  required: ["recipient", "amount", "mode", "purpose"],
1247
1291
  additionalProperties: false,
@@ -1249,7 +1293,7 @@ const solanaToolDefinitions = [
1249
1293
  },
1250
1294
  {
1251
1295
  name: "transfer_spl_token",
1252
- description: "Preview, prepare, or execute an SPL token transfer by mint address. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1296
+ description: "Preview, prepare, or execute an SPL token transfer by mint address. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1253
1297
  optional: true,
1254
1298
  parameters: {
1255
1299
  type: "object",
@@ -1261,7 +1305,6 @@ const solanaToolDefinitions = [
1261
1305
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1262
1306
  purpose: { type: "string" },
1263
1307
  user_intent: { type: "boolean" },
1264
- approval_token: { type: "string" },
1265
1308
  },
1266
1309
  required: ["recipient", "mint", "amount", "mode", "purpose"],
1267
1310
  additionalProperties: false,
@@ -1269,7 +1312,7 @@ const solanaToolDefinitions = [
1269
1312
  },
1270
1313
  {
1271
1314
  name: "swap_solana_tokens",
1272
- description: `Preview, prepare, or execute a Solana token swap via Jupiter. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation. ${WALLET_TOOL_ONLY_GUIDANCE}`,
1315
+ description: `Preview, prepare, or execute a Solana token swap via Jupiter. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically. ${WALLET_TOOL_ONLY_GUIDANCE}`,
1273
1316
  optional: true,
1274
1317
  parameters: {
1275
1318
  type: "object",
@@ -1281,7 +1324,6 @@ const solanaToolDefinitions = [
1281
1324
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1282
1325
  purpose: { type: "string" },
1283
1326
  user_intent: { type: "boolean" },
1284
- approval_token: { type: "string" },
1285
1327
  },
1286
1328
  required: ["input_mint", "output_mint", "amount", "mode", "purpose"],
1287
1329
  additionalProperties: false,
@@ -1289,7 +1331,7 @@ const solanaToolDefinitions = [
1289
1331
  },
1290
1332
  {
1291
1333
  name: "swap_solana_privately",
1292
- description: `Preview or create a Solana private payout through Houdini's anonymous routing. The initial implementation supports same-token private payouts only, such as SOL->SOL or USDC->USDC. Use preview first, then execute after explicit approval. The first execute creates the Houdini order and returns its deposit address; use continue_solana_private_swap to submit the funding transfer. ${WALLET_TOOL_ONLY_GUIDANCE}`,
1334
+ description: `Preview or create a Solana private payout through Houdini's anonymous routing. The initial implementation supports same-token private payouts only, such as SOL->SOL or USDC->USDC. Use preview first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically. The first execute creates the Houdini order and returns its deposit address; use continue_solana_private_swap to submit the funding transfer. ${WALLET_TOOL_ONLY_GUIDANCE}`,
1293
1335
  optional: true,
1294
1336
  parameters: {
1295
1337
  type: "object",
@@ -1302,7 +1344,6 @@ const solanaToolDefinitions = [
1302
1344
  mode: { type: "string", enum: ["preview", "execute"] },
1303
1345
  purpose: { type: "string" },
1304
1346
  user_intent: { type: "boolean" },
1305
- approval_token: { type: "string" },
1306
1347
  },
1307
1348
  required: ["input_token", "output_token", "destination_address", "amount", "mode", "purpose"],
1308
1349
  additionalProperties: false,
@@ -1311,15 +1352,13 @@ const solanaToolDefinitions = [
1311
1352
  {
1312
1353
  name: "continue_solana_private_swap",
1313
1354
  description:
1314
- "Continue a previously created Houdini private Solana payout and submit the funding transfer to the cached deposit address. Use this after swap_solana_privately execute has returned a pending order.",
1355
+ "Continue a previously created Houdini private Solana payout and submit the funding transfer to the cached deposit address. Use this after swap_solana_privately execute has returned a pending order; the OpenClaw plugin reuses the cached confirmation context automatically.",
1315
1356
  optional: true,
1316
1357
  parameters: {
1317
1358
  type: "object",
1318
1359
  properties: {
1319
1360
  houdini_id: { type: "string" },
1320
- approval_token: { type: "string" },
1321
1361
  },
1322
- required: ["approval_token"],
1323
1362
  additionalProperties: false,
1324
1363
  },
1325
1364
  },
@@ -1339,7 +1378,7 @@ const solanaToolDefinitions = [
1339
1378
  },
1340
1379
  {
1341
1380
  name: "swap_solana_lifi_cross_chain_tokens",
1342
- description: "Preview, prepare, or execute a Solana-origin cross-chain swap through LI.FI. This currently supports Solana as the source chain and ethereum/base as the destination chain. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1381
+ description: "Preview, prepare, or execute a Solana-origin cross-chain swap through LI.FI. This currently supports Solana as the source chain and ethereum/base as the destination chain. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1343
1382
  optional: true,
1344
1383
  parameters: {
1345
1384
  type: "object",
@@ -1356,7 +1395,6 @@ const solanaToolDefinitions = [
1356
1395
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1357
1396
  purpose: { type: "string" },
1358
1397
  user_intent: { type: "boolean" },
1359
- approval_token: { type: "string" },
1360
1398
  },
1361
1399
  required: [
1362
1400
  "input_token",
@@ -1372,7 +1410,7 @@ const solanaToolDefinitions = [
1372
1410
  },
1373
1411
  {
1374
1412
  name: "claim_bags_fees",
1375
- description: "Preview, prepare, or execute a Bags fee-share claim for the connected wallet on mainnet. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1413
+ description: "Preview, prepare, or execute a Bags fee-share claim for the connected wallet on mainnet. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1376
1414
  optional: true,
1377
1415
  parameters: {
1378
1416
  type: "object",
@@ -1381,7 +1419,6 @@ const solanaToolDefinitions = [
1381
1419
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1382
1420
  purpose: { type: "string" },
1383
1421
  user_intent: { type: "boolean" },
1384
- approval_token: { type: "string" },
1385
1422
  },
1386
1423
  required: ["token_mint", "mode", "purpose"],
1387
1424
  additionalProperties: false,
@@ -1389,7 +1426,7 @@ const solanaToolDefinitions = [
1389
1426
  },
1390
1427
  {
1391
1428
  name: "launch_bags_token",
1392
- description: "Preview, prepare, or execute a Bags token launch with fee-share config on mainnet. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1429
+ description: "Preview, prepare, or execute a Bags token launch with fee-share config on mainnet. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1393
1430
  optional: true,
1394
1431
  parameters: {
1395
1432
  type: "object",
@@ -1416,7 +1453,6 @@ const solanaToolDefinitions = [
1416
1453
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1417
1454
  purpose: { type: "string" },
1418
1455
  user_intent: { type: "boolean" },
1419
- approval_token: { type: "string" },
1420
1456
  },
1421
1457
  required: [
1422
1458
  "name",
@@ -1434,7 +1470,7 @@ const solanaToolDefinitions = [
1434
1470
  },
1435
1471
  {
1436
1472
  name: "jupiter_earn_deposit",
1437
- description: "Preview, prepare, or execute a Jupiter Earn deposit using a raw base-unit amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1473
+ description: "Preview, prepare, or execute a Jupiter Earn deposit using a raw base-unit amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1438
1474
  optional: true,
1439
1475
  parameters: {
1440
1476
  type: "object",
@@ -1444,7 +1480,6 @@ const solanaToolDefinitions = [
1444
1480
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1445
1481
  purpose: { type: "string" },
1446
1482
  user_intent: { type: "boolean" },
1447
- approval_token: { type: "string" },
1448
1483
  },
1449
1484
  required: ["asset", "amount_raw", "mode", "purpose"],
1450
1485
  additionalProperties: false,
@@ -1452,7 +1487,7 @@ const solanaToolDefinitions = [
1452
1487
  },
1453
1488
  {
1454
1489
  name: "jupiter_earn_withdraw",
1455
- description: "Preview, prepare, or execute a Jupiter Earn withdraw using a raw base-unit amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1490
+ description: "Preview, prepare, or execute a Jupiter Earn withdraw using a raw base-unit amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1456
1491
  optional: true,
1457
1492
  parameters: {
1458
1493
  type: "object",
@@ -1462,7 +1497,6 @@ const solanaToolDefinitions = [
1462
1497
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1463
1498
  purpose: { type: "string" },
1464
1499
  user_intent: { type: "boolean" },
1465
- approval_token: { type: "string" },
1466
1500
  },
1467
1501
  required: ["asset", "amount_raw", "mode", "purpose"],
1468
1502
  additionalProperties: false,
@@ -1470,7 +1504,7 @@ const solanaToolDefinitions = [
1470
1504
  },
1471
1505
  {
1472
1506
  name: "kamino_lend_deposit",
1473
- description: "Preview, prepare, or execute a Kamino lending deposit using a decimal token amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1507
+ description: "Preview, prepare, or execute a Kamino lending deposit using a decimal token amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1474
1508
  optional: true,
1475
1509
  parameters: {
1476
1510
  type: "object",
@@ -1481,7 +1515,6 @@ const solanaToolDefinitions = [
1481
1515
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1482
1516
  purpose: { type: "string" },
1483
1517
  user_intent: { type: "boolean" },
1484
- approval_token: { type: "string" },
1485
1518
  },
1486
1519
  required: ["market", "reserve", "amount_ui", "mode", "purpose"],
1487
1520
  additionalProperties: false,
@@ -1489,7 +1522,7 @@ const solanaToolDefinitions = [
1489
1522
  },
1490
1523
  {
1491
1524
  name: "kamino_lend_withdraw",
1492
- description: "Preview, prepare, or execute a Kamino lending withdraw using a decimal token amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1525
+ description: "Preview, prepare, or execute a Kamino lending withdraw using a decimal token amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1493
1526
  optional: true,
1494
1527
  parameters: {
1495
1528
  type: "object",
@@ -1500,7 +1533,6 @@ const solanaToolDefinitions = [
1500
1533
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1501
1534
  purpose: { type: "string" },
1502
1535
  user_intent: { type: "boolean" },
1503
- approval_token: { type: "string" },
1504
1536
  },
1505
1537
  required: ["market", "reserve", "amount_ui", "mode", "purpose"],
1506
1538
  additionalProperties: false,
@@ -1508,7 +1540,7 @@ const solanaToolDefinitions = [
1508
1540
  },
1509
1541
  {
1510
1542
  name: "kamino_lend_borrow",
1511
- description: "Preview, prepare, or execute a Kamino lending borrow using a decimal token amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1543
+ description: "Preview, prepare, or execute a Kamino lending borrow using a decimal token amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1512
1544
  optional: true,
1513
1545
  parameters: {
1514
1546
  type: "object",
@@ -1519,7 +1551,6 @@ const solanaToolDefinitions = [
1519
1551
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1520
1552
  purpose: { type: "string" },
1521
1553
  user_intent: { type: "boolean" },
1522
- approval_token: { type: "string" },
1523
1554
  },
1524
1555
  required: ["market", "reserve", "amount_ui", "mode", "purpose"],
1525
1556
  additionalProperties: false,
@@ -1527,7 +1558,7 @@ const solanaToolDefinitions = [
1527
1558
  },
1528
1559
  {
1529
1560
  name: "kamino_lend_repay",
1530
- description: "Preview, prepare, or execute a Kamino lending repay using a decimal token amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1561
+ description: "Preview, prepare, or execute a Kamino lending repay using a decimal token amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1531
1562
  optional: true,
1532
1563
  parameters: {
1533
1564
  type: "object",
@@ -1538,7 +1569,6 @@ const solanaToolDefinitions = [
1538
1569
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1539
1570
  purpose: { type: "string" },
1540
1571
  user_intent: { type: "boolean" },
1541
- approval_token: { type: "string" },
1542
1572
  },
1543
1573
  required: ["market", "reserve", "amount_ui", "mode", "purpose"],
1544
1574
  additionalProperties: false,
@@ -1579,7 +1609,6 @@ const solanaToolDefinitions = [
1579
1609
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1580
1610
  purpose: { type: "string" },
1581
1611
  user_intent: { type: "boolean" },
1582
- approval_token: { type: "string" },
1583
1612
  },
1584
1613
  required: [
1585
1614
  "pool_name",
@@ -1617,7 +1646,6 @@ const solanaToolDefinitions = [
1617
1646
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1618
1647
  purpose: { type: "string" },
1619
1648
  user_intent: { type: "boolean" },
1620
- approval_token: { type: "string" },
1621
1649
  },
1622
1650
  required: ["pool_name", "market_symbol", "side", "mode", "purpose"],
1623
1651
  additionalProperties: false,
@@ -1625,7 +1653,7 @@ const solanaToolDefinitions = [
1625
1653
  },
1626
1654
  {
1627
1655
  name: "close_empty_token_accounts",
1628
- description: "Preview or execute closing zero-balance token accounts. Execute requires a host-issued approval token bound to the previewed operation.",
1656
+ description: "Preview or execute closing zero-balance token accounts. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1629
1657
  optional: true,
1630
1658
  parameters: {
1631
1659
  type: "object",
@@ -1633,7 +1661,6 @@ const solanaToolDefinitions = [
1633
1661
  limit: { type: "integer" },
1634
1662
  mode: { type: "string", enum: ["preview", "execute"] },
1635
1663
  purpose: { type: "string" },
1636
- approval_token: { type: "string" },
1637
1664
  },
1638
1665
  required: ["limit", "mode", "purpose"],
1639
1666
  additionalProperties: false,
@@ -1710,7 +1737,7 @@ const btcToolDefinitions = [
1710
1737
  },
1711
1738
  {
1712
1739
  name: "transfer_btc",
1713
- description: "Preview, prepare, or execute a BTC transfer in satoshis. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1740
+ description: "Preview, prepare, or execute a BTC transfer in satoshis. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1714
1741
  optional: true,
1715
1742
  parameters: {
1716
1743
  type: "object",
@@ -1722,7 +1749,6 @@ const btcToolDefinitions = [
1722
1749
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1723
1750
  purpose: { type: "string" },
1724
1751
  user_intent: { type: "boolean" },
1725
- approval_token: { type: "string" },
1726
1752
  },
1727
1753
  required: ["recipient", "amount_sats", "mode", "purpose"],
1728
1754
  additionalProperties: false,
@@ -1938,7 +1964,7 @@ const evmToolDefinitions = [
1938
1964
  },
1939
1965
  {
1940
1966
  name: "manage_evm_aave_position",
1941
- description: "Preview, prepare, or execute a narrow Aave V3 lending operation on supported EVM mainnet networks. Supported operations are supply, withdraw, borrow, and repay. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
1967
+ description: "Preview, prepare, or execute a narrow Aave V3 lending operation on supported EVM mainnet networks. Supported operations are supply, withdraw, borrow, and repay. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1942
1968
  optional: true,
1943
1969
  parameters: {
1944
1970
  type: "object",
@@ -1949,7 +1975,6 @@ const evmToolDefinitions = [
1949
1975
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1950
1976
  purpose: { type: "string" },
1951
1977
  user_intent: { type: "boolean" },
1952
- approval_token: { type: "string" },
1953
1978
  network: { type: "string", enum: ["ethereum", "base"] },
1954
1979
  },
1955
1980
  required: ["operation", "token_address", "amount_raw", "mode", "purpose"],
@@ -1980,7 +2005,7 @@ const evmToolDefinitions = [
1980
2005
  },
1981
2006
  {
1982
2007
  name: "manage_evm_lido_position",
1983
- description: "Preview, prepare, or execute a narrow Lido staking operation on Ethereum mainnet. Supported operations are stake_eth_for_wsteth, wrap_steth, and unwrap_wsteth. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
2008
+ description: "Preview, prepare, or execute a narrow Lido staking operation on Ethereum mainnet. Supported operations are stake_eth_for_wsteth, wrap_steth, and unwrap_wsteth. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1984
2009
  optional: true,
1985
2010
  parameters: {
1986
2011
  type: "object",
@@ -1990,7 +2015,6 @@ const evmToolDefinitions = [
1990
2015
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1991
2016
  purpose: { type: "string" },
1992
2017
  user_intent: { type: "boolean" },
1993
- approval_token: { type: "string" },
1994
2018
  network: { type: "string", enum: ["ethereum"] },
1995
2019
  },
1996
2020
  required: ["operation", "amount_raw", "mode", "purpose"],
@@ -2010,7 +2034,7 @@ const evmToolDefinitions = [
2010
2034
  },
2011
2035
  {
2012
2036
  name: "manage_evm_lido_withdrawal",
2013
- description: "Preview, prepare, or execute a narrow Lido withdrawal queue operation on Ethereum mainnet. Supported operations are request_withdrawal_steth, request_withdrawal_wsteth, and claim_withdrawal. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
2037
+ description: "Preview, prepare, or execute a narrow Lido withdrawal queue operation on Ethereum mainnet. Supported operations are request_withdrawal_steth, request_withdrawal_wsteth, and claim_withdrawal. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
2014
2038
  optional: true,
2015
2039
  parameters: {
2016
2040
  type: "object",
@@ -2024,7 +2048,6 @@ const evmToolDefinitions = [
2024
2048
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2025
2049
  purpose: { type: "string" },
2026
2050
  user_intent: { type: "boolean" },
2027
- approval_token: { type: "string" },
2028
2051
  network: { type: "string", enum: ["ethereum"] },
2029
2052
  },
2030
2053
  required: ["operation", "mode", "purpose"],
@@ -2048,7 +2071,7 @@ const evmToolDefinitions = [
2048
2071
  },
2049
2072
  {
2050
2073
  name: "swap_evm_tokens",
2051
- description: "Preview, prepare, or execute an ERC-20 to ERC-20 swap through Velora on supported EVM mainnet networks. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
2074
+ description: "Preview, prepare, or execute an ERC-20 to ERC-20 swap through Velora on supported EVM mainnet networks. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
2052
2075
  optional: true,
2053
2076
  parameters: {
2054
2077
  type: "object",
@@ -2059,7 +2082,6 @@ const evmToolDefinitions = [
2059
2082
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2060
2083
  purpose: { type: "string" },
2061
2084
  user_intent: { type: "boolean" },
2062
- approval_token: { type: "string" },
2063
2085
  network: { type: "string", enum: ["ethereum", "base"] },
2064
2086
  },
2065
2087
  required: ["token_in", "token_out", "amount_in_raw", "mode", "purpose"],
@@ -2068,7 +2090,7 @@ const evmToolDefinitions = [
2068
2090
  },
2069
2091
  {
2070
2092
  name: "swap_evm_lifi_cross_chain_tokens",
2071
- description: "Preview, prepare, or execute an EVM-origin cross-chain swap through LI.FI. This currently supports ethereum/base as the source network and ethereum/base/solana as the destination chain. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
2093
+ description: "Preview, prepare, or execute an EVM-origin cross-chain swap through LI.FI. This currently supports ethereum/base as the source network and ethereum/base/solana as the destination chain. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
2072
2094
  optional: true,
2073
2095
  parameters: {
2074
2096
  type: "object",
@@ -2085,7 +2107,6 @@ const evmToolDefinitions = [
2085
2107
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2086
2108
  purpose: { type: "string" },
2087
2109
  user_intent: { type: "boolean" },
2088
- approval_token: { type: "string" },
2089
2110
  network: { type: "string", enum: ["ethereum", "base"] },
2090
2111
  },
2091
2112
  required: [
@@ -2102,7 +2123,7 @@ const evmToolDefinitions = [
2102
2123
  },
2103
2124
  {
2104
2125
  name: "transfer_evm_native",
2105
- description: "Preview, prepare, or execute a native EVM transfer using a wei amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
2126
+ description: "Preview, prepare, or execute a native EVM transfer using a wei amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
2106
2127
  optional: true,
2107
2128
  parameters: {
2108
2129
  type: "object",
@@ -2112,7 +2133,6 @@ const evmToolDefinitions = [
2112
2133
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2113
2134
  purpose: { type: "string" },
2114
2135
  user_intent: { type: "boolean" },
2115
- approval_token: { type: "string" },
2116
2136
  network: { type: "string", enum: ["ethereum", "base"] },
2117
2137
  },
2118
2138
  required: ["recipient", "amount_wei", "mode", "purpose"],
@@ -2121,7 +2141,7 @@ const evmToolDefinitions = [
2121
2141
  },
2122
2142
  {
2123
2143
  name: "transfer_evm_token",
2124
- description: "Preview, prepare, or execute an ERC-20 transfer using a raw base-unit amount. Prepare returns an execution plan only, and execute requires a host-issued approval token bound to the previewed operation.",
2144
+ description: "Preview, prepare, or execute an ERC-20 transfer using a raw base-unit amount. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
2125
2145
  optional: true,
2126
2146
  parameters: {
2127
2147
  type: "object",
@@ -2132,7 +2152,6 @@ const evmToolDefinitions = [
2132
2152
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2133
2153
  purpose: { type: "string" },
2134
2154
  user_intent: { type: "boolean" },
2135
- approval_token: { type: "string" },
2136
2155
  network: { type: "string", enum: ["ethereum", "base"] },
2137
2156
  },
2138
2157
  required: ["token_address", "recipient", "amount_raw", "mode", "purpose"],