@quackai/q402-mcp 0.8.38 → 0.8.40
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 +19 -3
- package/package.json +1 -1
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.
|
|
214
|
+
version: "0.8.40",
|
|
215
215
|
description: "MCP server for Q402 \u2014 gasless USDC/USDT/RLUSD payments on 11 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: [
|
|
@@ -974,6 +974,9 @@ function checkConsent(intent, provided) {
|
|
|
974
974
|
// src/tools/pay.ts
|
|
975
975
|
var PayInputSchema = z2.object({
|
|
976
976
|
chain: z2.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum", "base"]),
|
|
977
|
+
rail: z2.enum(["q402", "x402"]).optional().describe(
|
|
978
|
+
'Settlement rail. Base only \u2014 leave unset everywhere else. "q402" (default) = Q402 gasless EIP-7702 (USDC + USDT). "x402" = the Coinbase x402 standard (EIP-3009 USDC transferWithAuthorization), settled gaslessly by the Q402 facilitator \u2014 Base USDC only, no Hooks. walletMode="agentic-server" only.'
|
|
979
|
+
),
|
|
977
980
|
to: z2.string().refine(isAddress2, "to must be a valid 0x-prefixed EVM address").describe("Recipient EVM address (0x + 40 hex)."),
|
|
978
981
|
amount: z2.string().regex(/^\d+(\.\d+)?$/, "amount must be a positive decimal string").describe('Human-readable decimal amount, e.g. "5.00".'),
|
|
979
982
|
token: z2.enum(["USDC", "USDT", "RLUSD"]).describe(
|
|
@@ -1139,6 +1142,12 @@ async function runPay(input) {
|
|
|
1139
1142
|
to: input.to.toLowerCase(),
|
|
1140
1143
|
amount: input.amount,
|
|
1141
1144
|
token: input.token,
|
|
1145
|
+
// Bind the settlement RAIL. On Base the same (to, amount, token) settles
|
|
1146
|
+
// very differently under q402 (EIP-7702) vs x402 (EIP-3009) — different
|
|
1147
|
+
// signature scheme, gas path, and wallet-state constraints. Consenting to a
|
|
1148
|
+
// Q402-rail preview must NOT authorise an x402 execution on the same token,
|
|
1149
|
+
// so a rail change invalidates the consent and forces a fresh preview.
|
|
1150
|
+
rail: input.rail ?? "q402",
|
|
1142
1151
|
// Bind the funding source too — the user is consenting to spend from THIS
|
|
1143
1152
|
// wallet, so a different walletMode/walletId needs a fresh preview.
|
|
1144
1153
|
wm: effectiveMode,
|
|
@@ -1154,13 +1163,14 @@ async function runPay(input) {
|
|
|
1154
1163
|
if (!consent.ok) {
|
|
1155
1164
|
const splitNote = input.hookParams?.splits ? ` \u2014 split ${input.hookParams.splits.length} ways; funds go to the split recipients, not ${input.to}` : "";
|
|
1156
1165
|
const fromNote = senderWallet ? ` from ${senderWallet.addressShort}` : "";
|
|
1166
|
+
const railNote = input.rail === "x402" ? " via the x402 (EIP-3009) rail" : "";
|
|
1157
1167
|
return {
|
|
1158
1168
|
result: failureResult("consent"),
|
|
1159
1169
|
guardsApplied: [...guardsApplied, "two_phase_consent"],
|
|
1160
1170
|
senderWallet,
|
|
1161
1171
|
needsConsent: {
|
|
1162
1172
|
status: "needs_confirmation",
|
|
1163
|
-
preview: `Send ${input.amount} ${input.token} to ${input.to} on ${chain.key}${fromNote}${splitNote}. Confirm with the user, then re-call q402_pay with the same args plus consentToken="${consent.expected}".`,
|
|
1173
|
+
preview: `Send ${input.amount} ${input.token} to ${input.to} on ${chain.key}${railNote}${fromNote}${splitNote}. Confirm with the user, then re-call q402_pay with the same args plus consentToken="${consent.expected}".`,
|
|
1164
1174
|
consentToken: consent.expected
|
|
1165
1175
|
}
|
|
1166
1176
|
};
|
|
@@ -1227,7 +1237,8 @@ async function runPay(input) {
|
|
|
1227
1237
|
// the per-wallet hook dispatch, so forwarding here is the only
|
|
1228
1238
|
// place hookParams take effect. The landing route ignores them
|
|
1229
1239
|
// for owner-sig calls (trust boundary), so this is safe.
|
|
1230
|
-
...input.hookParams ? { hookParams: input.hookParams } : {}
|
|
1240
|
+
...input.hookParams ? { hookParams: input.hookParams } : {},
|
|
1241
|
+
...input.rail ? { rail: input.rail } : {}
|
|
1231
1242
|
}),
|
|
1232
1243
|
signal: AbortSignal.timeout(6e4)
|
|
1233
1244
|
});
|
|
@@ -1413,6 +1424,11 @@ var PAY_TOOL = {
|
|
|
1413
1424
|
enum: CHAIN_KEYS,
|
|
1414
1425
|
description: "Target chain."
|
|
1415
1426
|
},
|
|
1427
|
+
rail: {
|
|
1428
|
+
type: "string",
|
|
1429
|
+
enum: ["q402", "x402"],
|
|
1430
|
+
description: 'Settlement rail (Base only). "q402" (default) = gasless EIP-7702 (USDC+USDT). "x402" = Coinbase x402 standard (EIP-3009), Base USDC only, agentic-server only. Leave unset elsewhere.'
|
|
1431
|
+
},
|
|
1416
1432
|
to: {
|
|
1417
1433
|
type: "string",
|
|
1418
1434
|
description: "Recipient EVM address (0x + 40 hex)."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quackai/q402-mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.40",
|
|
4
4
|
"description": "MCP server for Q402 — gasless USDC/USDT/RLUSD payments on 11 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": [
|