@agentlayer.tech/wallet 0.1.17 → 0.1.18

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.
@@ -25,6 +25,9 @@ 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 APPROVAL_PREVIEW_TOOL_ALIASES = new Map([
29
+ ["x402_pay_request", "x402_preview_request"],
30
+ ]);
28
31
 
29
32
  function canonicalJsonText(payload) {
30
33
  const normalize = (value) => {
@@ -51,6 +54,11 @@ function approvalCacheKey(userId, toolName) {
51
54
  return `${userId}::${toolName}`;
52
55
  }
53
56
 
57
+ function approvalPreviewToolName(toolName) {
58
+ const normalized = typeof toolName === "string" ? toolName.trim() : "";
59
+ return APPROVAL_PREVIEW_TOOL_ALIASES.get(normalized) || normalized;
60
+ }
61
+
54
62
  function pruneApprovalPreviewCache() {
55
63
  const now = Date.now();
56
64
  for (const [key, value] of approvalPreviewCache.entries()) {
@@ -61,29 +69,30 @@ function pruneApprovalPreviewCache() {
61
69
  }
62
70
 
63
71
  function cachePreviewForApproval(userId, toolName, payload) {
72
+ const cacheToolName = approvalPreviewToolName(toolName);
64
73
  if (!payload || payload.ok !== true || !payload.data || typeof payload.data !== "object") return;
65
74
  const preview = payload.data;
66
75
  if (preview.mode !== "preview") return;
67
76
  if (!preview.confirmation_summary || typeof preview.confirmation_summary !== "object") return;
68
77
  pruneApprovalPreviewCache();
69
78
  const digest = previewDigest(preview);
70
- approvalPreviewCache.set(approvalCacheKey(userId, toolName), {
79
+ approvalPreviewCache.set(approvalCacheKey(userId, cacheToolName), {
71
80
  digest,
72
81
  expiresAt:
73
- toolName === "swap_solana_privately"
82
+ cacheToolName === "swap_solana_privately"
74
83
  ? Date.now() + PRIVATE_SWAP_CACHE_TTL_MS
75
84
  : Date.now() + PREVIEW_CACHE_TTL_MS,
76
85
  preview,
77
86
  summary: preview.confirmation_summary,
78
87
  });
79
- if (toolName === "swap_solana_privately") {
80
- privateSwapOrderCache.delete(approvalCacheKey(userId, toolName));
88
+ if (cacheToolName === "swap_solana_privately") {
89
+ privateSwapOrderCache.delete(approvalCacheKey(userId, cacheToolName));
81
90
  }
82
91
  }
83
92
 
84
93
  function latestCachedPreview(userId, toolName) {
85
94
  pruneApprovalPreviewCache();
86
- return approvalPreviewCache.get(approvalCacheKey(userId, toolName)) || null;
95
+ return approvalPreviewCache.get(approvalCacheKey(userId, approvalPreviewToolName(toolName))) || null;
87
96
  }
88
97
 
89
98
  function approvalTokenPreviewDigest(token) {
@@ -498,8 +507,9 @@ async function issueApprovalToken(api, config, userId, toolName, previewPayload)
498
507
  if (!summary || typeof summary !== "object") {
499
508
  throw new Error(`No confirmation_summary available for ${toolName}.`);
500
509
  }
501
- const digest = previewDigest(previewPayload);
502
- const summaryForToken = { ...summary, _preview_digest: digest };
510
+ const summaryForToken = PREVIEW_BOUND_SWAP_TOOLS.has(toolName)
511
+ ? { ...summary, _preview_digest: previewDigest(previewPayload) }
512
+ : { ...summary };
503
513
  const extraArgs = [
504
514
  "--tool",
505
515
  toolName,
@@ -819,6 +829,94 @@ const walletSessionToolDefinitions = [
819
829
  additionalProperties: false,
820
830
  },
821
831
  },
832
+ {
833
+ name: "x402_search_services",
834
+ description:
835
+ "Search x402-paid services through CDP Bazaar or Agentic Market. This is read-only discovery and does not spend funds.",
836
+ parameters: {
837
+ type: "object",
838
+ properties: {
839
+ query: { type: "string" },
840
+ discovery_provider: {
841
+ type: "string",
842
+ enum: ["auto", "cdp_bazaar", "agentic_market"],
843
+ },
844
+ network: { type: "string" },
845
+ asset: { type: "string" },
846
+ scheme: { type: "string" },
847
+ max_usd_price: { type: "string" },
848
+ limit: { type: "integer" },
849
+ },
850
+ additionalProperties: false,
851
+ },
852
+ },
853
+ {
854
+ name: "x402_get_service_details",
855
+ description:
856
+ "Resolve one x402 service or resource into a normalized details payload. Use a resource URL for CDP Bazaar or a domain/service id for Agentic Market.",
857
+ parameters: {
858
+ type: "object",
859
+ properties: {
860
+ reference: { type: "string" },
861
+ discovery_provider: {
862
+ type: "string",
863
+ enum: ["auto", "cdp_bazaar", "agentic_market"],
864
+ },
865
+ },
866
+ required: ["reference"],
867
+ additionalProperties: false,
868
+ },
869
+ },
870
+ {
871
+ name: "x402_preview_request",
872
+ description:
873
+ "Make an unpaid HTTP request to an x402 endpoint, detect HTTP 402, parse PAYMENT-REQUIRED, and summarize the payment options. This does not pay or execute.",
874
+ parameters: {
875
+ type: "object",
876
+ properties: {
877
+ url: { type: "string" },
878
+ method: { type: "string" },
879
+ headers: { type: "object", additionalProperties: { type: "string" } },
880
+ query: { type: "object", additionalProperties: true },
881
+ json_body: {},
882
+ text_body: { type: "string" },
883
+ },
884
+ required: ["url"],
885
+ additionalProperties: false,
886
+ },
887
+ },
888
+ {
889
+ name: "x402_pay_request",
890
+ 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.",
892
+ parameters: {
893
+ type: "object",
894
+ properties: {
895
+ url: { type: "string" },
896
+ method: { type: "string" },
897
+ headers: { type: "object", additionalProperties: { type: "string" } },
898
+ query: { type: "object", additionalProperties: true },
899
+ json_body: {},
900
+ text_body: { type: "string" },
901
+ mode: {
902
+ type: "string",
903
+ enum: ["prepare", "execute"],
904
+ description: "prepare validates the payment plan; execute sends the paid retry.",
905
+ },
906
+ purpose: { type: "string" },
907
+ user_intent: {
908
+ type: "boolean",
909
+ description: "Must be true for prepare mode.",
910
+ },
911
+ approval_token: {
912
+ type: "string",
913
+ description: "Required for execute mode and must be issued against the exact x402 payment summary.",
914
+ },
915
+ },
916
+ required: ["url", "mode", "purpose"],
917
+ additionalProperties: false,
918
+ },
919
+ },
822
920
  {
823
921
  name: "get_active_wallet_backend",
824
922
  description: "Show which wallet backend is active in this OpenClaw plugin session and whether it differs from the startup plugin config.",
@@ -25,6 +25,9 @@ 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 APPROVAL_PREVIEW_TOOL_ALIASES = new Map([
29
+ ["x402_pay_request", "x402_preview_request"],
30
+ ]);
28
31
 
29
32
  function canonicalJsonText(payload) {
30
33
  const normalize = (value) => {
@@ -51,6 +54,11 @@ function approvalCacheKey(userId, toolName) {
51
54
  return `${userId}::${toolName}`;
52
55
  }
53
56
 
57
+ function approvalPreviewToolName(toolName) {
58
+ const normalized = typeof toolName === "string" ? toolName.trim() : "";
59
+ return APPROVAL_PREVIEW_TOOL_ALIASES.get(normalized) || normalized;
60
+ }
61
+
54
62
  function pruneApprovalPreviewCache() {
55
63
  const now = Date.now();
56
64
  for (const [key, value] of approvalPreviewCache.entries()) {
@@ -61,29 +69,30 @@ function pruneApprovalPreviewCache() {
61
69
  }
62
70
 
63
71
  function cachePreviewForApproval(userId, toolName, payload) {
72
+ const cacheToolName = approvalPreviewToolName(toolName);
64
73
  if (!payload || payload.ok !== true || !payload.data || typeof payload.data !== "object") return;
65
74
  const preview = payload.data;
66
75
  if (preview.mode !== "preview") return;
67
76
  if (!preview.confirmation_summary || typeof preview.confirmation_summary !== "object") return;
68
77
  pruneApprovalPreviewCache();
69
78
  const digest = previewDigest(preview);
70
- approvalPreviewCache.set(approvalCacheKey(userId, toolName), {
79
+ approvalPreviewCache.set(approvalCacheKey(userId, cacheToolName), {
71
80
  digest,
72
81
  expiresAt:
73
- toolName === "swap_solana_privately"
82
+ cacheToolName === "swap_solana_privately"
74
83
  ? Date.now() + PRIVATE_SWAP_CACHE_TTL_MS
75
84
  : Date.now() + PREVIEW_CACHE_TTL_MS,
76
85
  preview,
77
86
  summary: preview.confirmation_summary,
78
87
  });
79
- if (toolName === "swap_solana_privately") {
80
- privateSwapOrderCache.delete(approvalCacheKey(userId, toolName));
88
+ if (cacheToolName === "swap_solana_privately") {
89
+ privateSwapOrderCache.delete(approvalCacheKey(userId, cacheToolName));
81
90
  }
82
91
  }
83
92
 
84
93
  function latestCachedPreview(userId, toolName) {
85
94
  pruneApprovalPreviewCache();
86
- return approvalPreviewCache.get(approvalCacheKey(userId, toolName)) || null;
95
+ return approvalPreviewCache.get(approvalCacheKey(userId, approvalPreviewToolName(toolName))) || null;
87
96
  }
88
97
 
89
98
  function approvalTokenPreviewDigest(token) {
@@ -498,8 +507,9 @@ async function issueApprovalToken(api, config, userId, toolName, previewPayload)
498
507
  if (!summary || typeof summary !== "object") {
499
508
  throw new Error(`No confirmation_summary available for ${toolName}.`);
500
509
  }
501
- const digest = previewDigest(previewPayload);
502
- const summaryForToken = { ...summary, _preview_digest: digest };
510
+ const summaryForToken = PREVIEW_BOUND_SWAP_TOOLS.has(toolName)
511
+ ? { ...summary, _preview_digest: previewDigest(previewPayload) }
512
+ : { ...summary };
503
513
  const extraArgs = [
504
514
  "--tool",
505
515
  toolName,
@@ -819,6 +829,94 @@ const walletSessionToolDefinitions = [
819
829
  additionalProperties: false,
820
830
  },
821
831
  },
832
+ {
833
+ name: "x402_search_services",
834
+ description:
835
+ "Search x402-paid services through CDP Bazaar or Agentic Market. This is read-only discovery and does not spend funds.",
836
+ parameters: {
837
+ type: "object",
838
+ properties: {
839
+ query: { type: "string" },
840
+ discovery_provider: {
841
+ type: "string",
842
+ enum: ["auto", "cdp_bazaar", "agentic_market"],
843
+ },
844
+ network: { type: "string" },
845
+ asset: { type: "string" },
846
+ scheme: { type: "string" },
847
+ max_usd_price: { type: "string" },
848
+ limit: { type: "integer" },
849
+ },
850
+ additionalProperties: false,
851
+ },
852
+ },
853
+ {
854
+ name: "x402_get_service_details",
855
+ description:
856
+ "Resolve one x402 service or resource into a normalized details payload. Use a resource URL for CDP Bazaar or a domain/service id for Agentic Market.",
857
+ parameters: {
858
+ type: "object",
859
+ properties: {
860
+ reference: { type: "string" },
861
+ discovery_provider: {
862
+ type: "string",
863
+ enum: ["auto", "cdp_bazaar", "agentic_market"],
864
+ },
865
+ },
866
+ required: ["reference"],
867
+ additionalProperties: false,
868
+ },
869
+ },
870
+ {
871
+ name: "x402_preview_request",
872
+ description:
873
+ "Make an unpaid HTTP request to an x402 endpoint, detect HTTP 402, parse PAYMENT-REQUIRED, and summarize the payment options. This does not pay or execute.",
874
+ parameters: {
875
+ type: "object",
876
+ properties: {
877
+ url: { type: "string" },
878
+ method: { type: "string" },
879
+ headers: { type: "object", additionalProperties: { type: "string" } },
880
+ query: { type: "object", additionalProperties: true },
881
+ json_body: {},
882
+ text_body: { type: "string" },
883
+ },
884
+ required: ["url"],
885
+ additionalProperties: false,
886
+ },
887
+ },
888
+ {
889
+ name: "x402_pay_request",
890
+ 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.",
892
+ parameters: {
893
+ type: "object",
894
+ properties: {
895
+ url: { type: "string" },
896
+ method: { type: "string" },
897
+ headers: { type: "object", additionalProperties: { type: "string" } },
898
+ query: { type: "object", additionalProperties: true },
899
+ json_body: {},
900
+ text_body: { type: "string" },
901
+ mode: {
902
+ type: "string",
903
+ enum: ["prepare", "execute"],
904
+ description: "prepare validates the payment plan; execute sends the paid retry.",
905
+ },
906
+ purpose: { type: "string" },
907
+ user_intent: {
908
+ type: "boolean",
909
+ description: "Must be true for prepare mode.",
910
+ },
911
+ approval_token: {
912
+ type: "string",
913
+ description: "Required for execute mode and must be issued against the exact x402 payment summary.",
914
+ },
915
+ },
916
+ required: ["url", "mode", "purpose"],
917
+ additionalProperties: false,
918
+ },
919
+ },
822
920
  {
823
921
  name: "get_active_wallet_backend",
824
922
  description: "Show which wallet backend is active in this OpenClaw plugin session and whether it differs from the startup plugin config.",
@@ -70,7 +70,11 @@
70
70
  "transfer_evm_native",
71
71
  "transfer_evm_token",
72
72
  "transfer_sol",
73
- "transfer_spl_token"
73
+ "transfer_spl_token",
74
+ "x402_get_service_details",
75
+ "x402_pay_request",
76
+ "x402_preview_request",
77
+ "x402_search_services"
74
78
  ]
75
79
  },
76
80
  "skills": ["skills/wallet-operator"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentlayertech/agent-wallet-plugin",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "OpenClaw plugin bridge for the AgentLayer wallet runtime.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN ../../../LICENSE",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentlayertech/pay-bridge-plugin",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "OpenClaw plugin bridge for the local pay.sh CLI.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN ../../../LICENSE",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v0.1.18 - 2026-05-19
6
+
7
+ - Started the native x402 buyer integration inside `agent-wallet` instead of
8
+ the separate `pay-bridge` wallet path.
9
+ - Added read-only x402 discovery helpers for `CDP Bazaar` and
10
+ `Agentic Market`, including normalized service/resource search results.
11
+ - Added `x402_preview_request`, which performs an unpaid request, parses
12
+ `PAYMENT-REQUIRED`, and summarizes accepted payment options without spending
13
+ funds.
14
+ - Added `x402_pay_request` with `prepare` and `execute` flow for exact buyer
15
+ payments from the native wallet on Solana, Base, and Base Sepolia.
16
+ - Added buyer-side x402 signing support to the local EVM runtime so Base
17
+ payments execute without requiring a separate wallet product.
18
+ - Fixed x402 Solana execution against hosted RPC routing by deriving an
19
+ SDK-compatible direct Solana RPC URL for the x402 SVM client.
20
+ - Fixed x402 payment requirement selection so SDK model objects survive through
21
+ prepare and execute without crashing on plain dict access.
22
+ - Added automatic host approval-token issuance for `x402_pay_request` from the
23
+ cached `x402_preview_request` summary in the OpenClaw bridge.
24
+ - Fixed x402 approval-token binding so execute validates against the exact
25
+ `confirmation_summary` used by the Python wallet policy gate.
26
+ - Synced the OpenClaw coding profile allowlist and runtime bundle so the new
27
+ x402 tools are exposed correctly in packaged installs.
28
+
5
29
  ## v0.1.17 - 2026-05-17
6
30
 
7
31
  - Added Flash Trade collateral-aware perp opens so the Solana wallet flow can
@@ -108,6 +108,10 @@ Current safe tools:
108
108
  - `deactivate_solana_stake`
109
109
  - `withdraw_solana_stake`
110
110
  - `request_devnet_airdrop`
111
+ - `x402_search_services`
112
+ - `x402_get_service_details`
113
+ - `x402_preview_request`
114
+ - `x402_pay_request`
111
115
 
112
116
  Temporarily disabled but kept in the codebase for later re-enable:
113
117