@quackai/q402-mcp 0.8.32 → 0.8.33

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/README.md CHANGED
@@ -184,9 +184,9 @@ Then export the values in `~/.zshrc` / `~/.bashrc`. See the [Codex config refere
184
184
  | `q402_yield_positions` | api key | Show the Agent Wallet's open Q402 Yield positions (balance, principal, accrued interest, APY) + total supplied in USD. Mode C. |
185
185
  | `q402_yield_deposit` | live mode | Supply the Agent Wallet's USDC/USDT into Aave V3 (Q402 Yield) to earn supply APY. Mode C, BNB-only. Requires `confirm: true`; sandbox-by-default. |
186
186
  | `q402_yield_withdraw` | live mode | Withdraw supplied USDC/USDT out of Aave V3 back to the Agent Wallet (`amount: "max"` = full position). Mode C, BNB-only. Requires `confirm: true`; sandbox-by-default. |
187
- | `q402_request_create` | api key | Publish a payment request (invoice). No funds move returns a shareable `/pay` link + `req_…` id. Recipient defaults to the Agent Wallet. |
187
+ | `q402_request_create` | api key | Publish a payment request (invoice). No funds move; returns a shareable `/pay` link + `req_…` id. Recipient defaults to the Agent Wallet. |
188
188
  | `q402_request_status` | none | Look up a payment request by `req_…` id (amount, token, chain, recipient, status). Read-only; `notFound` instead of throwing. |
189
- | `q402_request_pay` | live mode | Pay a request gaslessly from the payer's own Agent Wallet (Mode C). Terms come from the stored request can't be redirected. Requires `confirm: true`. |
189
+ | `q402_request_pay` | live mode | Pay a request gaslessly from the payer's own Agent Wallet (Mode C). Terms come from the stored request, so they can't be redirected. Two-phase consent (same as `q402_pay`). |
190
190
 
191
191
  `q402_pay` + `q402_batch_pay` + `q402_bridge_send` + `q402_yield_deposit` + `q402_yield_withdraw` + `q402_request_pay` require explicit in-chat confirmation. Batch confirmation = full batch, not per-row.
192
192
 
package/dist/index.js CHANGED
@@ -211,7 +211,7 @@ var isValidPrivateKey = (s) => typeof s === "string" && PRIVATE_KEY_RE.test(s);
211
211
  // package.json
212
212
  var package_default = {
213
213
  name: "@quackai/q402-mcp",
214
- version: "0.8.32",
214
+ version: "0.8.33",
215
215
  description: "MCP server for Q402 \u2014 gasless USDC/USDT/RLUSD payments on 10 EVM chains + Chainlink CCIP USDC bridge on the eth/avax/arbitrum triangle, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.",
216
216
  mcpName: "io.github.bitgett/q402-mcp",
217
217
  keywords: [
@@ -279,7 +279,9 @@ var package_default = {
279
279
  access: "public"
280
280
  },
281
281
  overrides: {
282
- esbuild: "^0.28.1"
282
+ esbuild: "^0.28.1",
283
+ ws: "^8.21.0",
284
+ hono: "^4.12.25"
283
285
  }
284
286
  };
285
287
 
@@ -4945,7 +4947,10 @@ import { z as z27 } from "zod";
4945
4947
  var RequestPayInputSchema = z27.object({
4946
4948
  requestId: z27.string().regex(/^req_[0-9a-f]{24}$/, "requestId must match req_<24-hex>").describe("The payment request to pay (req_ + 24 hex). Get it from a /pay link, a 402 response, or whoever billed you."),
4947
4949
  confirm: z27.literal(true).describe(
4948
- "REQUIRED. Must be literally `true`. Paying a request moves real funds from your Agent Wallet. Echo back the amount + token + recipient + chain from q402_request_status, get an explicit user yes, and ONLY then call with confirm:true. Same guard as q402_pay."
4950
+ "REQUIRED. Must be literally `true`. Acknowledges this moves real funds from your Agent Wallet."
4951
+ ),
4952
+ consentToken: z27.string().optional().describe(
4953
+ 'Two-phase consent, identical to q402_pay. Call FIRST WITHOUT it: the tool moves no money and returns status="needs_consent" with a `preview` of the exact payment plus a `consentToken`. Relay the preview to the user, get an explicit yes, then re-call with the SAME requestId PLUS this consentToken. The token is re-derived from the request\'s terms, so a previewed payment cannot be swapped for a different one. confirm:true alone does NOT fire a payment.'
4949
4954
  ),
4950
4955
  walletId: z27.string().optional().describe("Optional lowercased Agent Wallet address to pay from when you hold multiple. Defaults to Q402_AGENT_WALLET_ADDRESS, then the server default.")
4951
4956
  });
@@ -4973,6 +4978,31 @@ async function runRequestPay(input) {
4973
4978
  if (CONFIG.allowedRecipients.length > 0 && !CONFIG.allowedRecipients.includes(req.recipient.toLowerCase())) {
4974
4979
  return { ok: false, status: "not_payable", requestId: req.id, txHash: null, receiptId: null, ...terms, error: "RECIPIENT_NOT_ALLOWED", message: `Recipient ${req.recipient} is not in Q402_ALLOWED_RECIPIENTS.` };
4975
4980
  }
4981
+ const consentIntent = {
4982
+ t: "request_pay",
4983
+ requestId: req.id,
4984
+ to: req.recipient.toLowerCase(),
4985
+ amount: req.amount,
4986
+ token: req.token,
4987
+ chain: req.chain
4988
+ };
4989
+ const consent = checkConsent(consentIntent, input.consentToken);
4990
+ if (!consent.ok) {
4991
+ return {
4992
+ ok: false,
4993
+ status: "needs_consent",
4994
+ requestId: req.id,
4995
+ txHash: null,
4996
+ receiptId: null,
4997
+ ...terms,
4998
+ message: "Relay this preview to the user and get an explicit yes, then re-call with the same requestId plus consentToken. No funds moved.",
4999
+ needsConsent: {
5000
+ status: "needs_confirmation",
5001
+ preview: `Pay ${req.amount} ${req.token} to ${req.recipient} on ${req.chain} (request ${req.id}).`,
5002
+ consentToken: consent.expected
5003
+ }
5004
+ };
5005
+ }
4976
5006
  const resolved = resolveApiKey(req.chain, "auto");
4977
5007
  if (!resolved.apiKey || !resolved.apiKey.startsWith("q402_live_")) {
4978
5008
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quackai/q402-mcp",
3
- "version": "0.8.32",
3
+ "version": "0.8.33",
4
4
  "description": "MCP server for Q402 — gasless USDC/USDT/RLUSD payments on 10 EVM chains + Chainlink CCIP USDC bridge on the eth/avax/arbitrum triangle, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.",
5
5
  "mcpName": "io.github.bitgett/q402-mcp",
6
6
  "keywords": [
@@ -68,6 +68,8 @@
68
68
  "access": "public"
69
69
  },
70
70
  "overrides": {
71
- "esbuild": "^0.28.1"
71
+ "esbuild": "^0.28.1",
72
+ "ws": "^8.21.0",
73
+ "hono": "^4.12.25"
72
74
  }
73
75
  }