@quackai/q402-mcp 0.5.15 → 0.5.16
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 +10 -11
- package/dist/index.js +15 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -165,10 +165,10 @@ Then export the values in `~/.zshrc` / `~/.bashrc`. See the [Codex config refere
|
|
|
165
165
|
|
|
166
166
|
By default the MCP server operates in **sandbox mode**: `q402_pay` returns a random fake transaction hash with `success: false` and `sandbox: true`, no funds move, no gas-tank credit is consumed. That makes it safe to plug into any MCP client without worrying about an accidental payment — if the agent misreads the conversation and fires `q402_pay` before you intended, nothing moves AND the response cannot be mistaken for a confirmed settlement.
|
|
167
167
|
|
|
168
|
-
To enable real on-chain transactions, the resolved API key must be live (`q402_live_*`), `Q402_PRIVATE_KEY` must be set to a valid 32-byte hex key, and `Q402_ENABLE_REAL_PAYMENTS=1`. The block below is the template `q402_doctor` writes to `~/.q402/mcp.env` —
|
|
168
|
+
To enable real on-chain transactions, the resolved API key must be live (`q402_live_*`), `Q402_PRIVATE_KEY` must be set to a valid 32-byte hex key, and `Q402_ENABLE_REAL_PAYMENTS=1`. The block below is the template `q402_doctor` writes to `~/.q402/mcp.env` — the three secret lines ship empty (no `#` to remove, just paste the value on the right of `=`) and the live flag defaults to `1`. The live-mode gate only flips once a real key + valid 32-byte PK are populated, so saving the template as-is stays in sandbox automatically. Change the flag to `0` if you want to force sandbox even with real keys (e.g. for chained testing on a paid plan):
|
|
169
169
|
|
|
170
170
|
```bash
|
|
171
|
-
# Two-key model —
|
|
171
|
+
# Two-key model — fill ONE (or both for auto-routing).
|
|
172
172
|
# Auto-routing (same for q402_pay AND q402_batch_pay):
|
|
173
173
|
# chain="bnb" + Q402_TRIAL_API_KEY set → Trial (free sponsored)
|
|
174
174
|
# anything else → Multichain (paid 9-chain)
|
|
@@ -176,20 +176,19 @@ To enable real on-chain transactions, the resolved API key must be live (`q402_l
|
|
|
176
176
|
# status="ambiguous" instead of executing — agent asks user to pick.
|
|
177
177
|
# Override per call with keyScope: "auto" | "trial" | "multichain".
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
Q402_TRIAL_API_KEY= # BNB-only sponsored Trial key (from /event)
|
|
180
|
+
Q402_MULTICHAIN_API_KEY= # paid 9-chain key (per-chain Gas Tank)
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
Q402_PRIVATE_KEY= # signer for the payer EOA (0x + 64 hex chars)
|
|
183
183
|
|
|
184
184
|
# Live mode switch:
|
|
185
185
|
# 0 = sandbox (test mode, no funds move — every q402_pay returns a fake hash)
|
|
186
186
|
# 1 = real on-chain payments (live mode)
|
|
187
|
-
# Default
|
|
188
|
-
#
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
#
|
|
192
|
-
# testing on a paid plan).
|
|
187
|
+
# Default 1: real payments enabled. Safe because mode only flips to live
|
|
188
|
+
# when BOTH a live API key (q402_live_*) AND a valid 32-byte private
|
|
189
|
+
# key are populated above. Empty values fail the gate, so partial setups
|
|
190
|
+
# stay in sandbox with a hint. Change to 0 to force sandbox even with
|
|
191
|
+
# real keys (e.g. for chained testing on a paid plan).
|
|
193
192
|
Q402_ENABLE_REAL_PAYMENTS=1
|
|
194
193
|
```
|
|
195
194
|
|
package/dist/index.js
CHANGED
|
@@ -121,7 +121,8 @@ function loadConfig() {
|
|
|
121
121
|
const apiKeyKind = classifyApiKey(apiKey);
|
|
122
122
|
const privateKey = ENV.Q402_PRIVATE_KEY ?? null;
|
|
123
123
|
const realPaymentsRequested = ENV.Q402_ENABLE_REAL_PAYMENTS === "1";
|
|
124
|
-
const
|
|
124
|
+
const anyLiveKey = classifyApiKey(trialApiKey) === "live" || classifyApiKey(multichainApiKey) === "live" || classifyApiKey(legacyApiKey) === "live";
|
|
125
|
+
const live = realPaymentsRequested && anyLiveKey && typeof privateKey === "string" && privateKey.length > 0;
|
|
125
126
|
return {
|
|
126
127
|
trialApiKey,
|
|
127
128
|
multichainApiKey,
|
|
@@ -187,7 +188,7 @@ var isValidPrivateKey = (s) => typeof s === "string" && PRIVATE_KEY_RE.test(s);
|
|
|
187
188
|
|
|
188
189
|
// src/version.ts
|
|
189
190
|
var PACKAGE_NAME = "@quackai/q402-mcp";
|
|
190
|
-
var PACKAGE_VERSION = "0.5.
|
|
191
|
+
var PACKAGE_VERSION = "0.5.16";
|
|
191
192
|
|
|
192
193
|
// src/tools/quote.ts
|
|
193
194
|
import { z } from "zod";
|
|
@@ -1043,6 +1044,16 @@ async function runBatchPay(input) {
|
|
|
1043
1044
|
}
|
|
1044
1045
|
}
|
|
1045
1046
|
const scopeRequest = input.keyScope ?? "auto";
|
|
1047
|
+
if (scopeRequest === "trial" && input.recipients.length > RECIPIENT_LIMIT_TRIAL) {
|
|
1048
|
+
guardsApplied.push("trial_cap_exceeded");
|
|
1049
|
+
return {
|
|
1050
|
+
mode: "none",
|
|
1051
|
+
status: "trial_cap_exceeded",
|
|
1052
|
+
guardsApplied,
|
|
1053
|
+
senderWallet,
|
|
1054
|
+
setupHint: `keyScope="trial" caps at ${RECIPIENT_LIMIT_TRIAL} recipients per call (BNB-only sponsored). Your batch has ${input.recipients.length}. Either trim to the first ${RECIPIENT_LIMIT_TRIAL} recipients and re-invoke with keyScope="trial", or send the full batch on the paid Multichain key by re-invoking with keyScope="multichain" (charges the paid pool + Gas Tank, up to ${RECIPIENT_LIMIT_PAID} per call).`
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1046
1057
|
if (scopeRequest === "auto" && input.chain === "bnb" && CONFIG.trialApiKey && input.recipients.length > RECIPIENT_LIMIT_TRIAL) {
|
|
1047
1058
|
const overflow = input.recipients.length - RECIPIENT_LIMIT_TRIAL;
|
|
1048
1059
|
guardsApplied.push("batch_cap_ambiguous");
|
|
@@ -1722,11 +1733,12 @@ function mask2(key) {
|
|
|
1722
1733
|
}
|
|
1723
1734
|
function detectPhase() {
|
|
1724
1735
|
const anyKey = !!(CONFIG.trialApiKey || CONFIG.multichainApiKey || CONFIG.legacyApiKey);
|
|
1736
|
+
const anyLiveKey = classifyApiKey(CONFIG.trialApiKey) === "live" || classifyApiKey(CONFIG.multichainApiKey) === "live" || classifyApiKey(CONFIG.legacyApiKey) === "live";
|
|
1725
1737
|
const hasValidPrivateKey = isValidPrivateKey(CONFIG.privateKey);
|
|
1726
1738
|
if (!Q402_ENV_FILE_PRESENT && !anyKey && !CONFIG.privateKey) {
|
|
1727
1739
|
return "first-install";
|
|
1728
1740
|
}
|
|
1729
|
-
const allEssentials = anyKey && hasValidPrivateKey && CONFIG.realPaymentsRequested &&
|
|
1741
|
+
const allEssentials = anyKey && hasValidPrivateKey && CONFIG.realPaymentsRequested && anyLiveKey;
|
|
1730
1742
|
if (allEssentials) return "live-check";
|
|
1731
1743
|
if (anyKey || CONFIG.privateKey || Q402_ENV_FILE_PRESENT) return "needs-completion";
|
|
1732
1744
|
return "first-install";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quackai/q402-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.16",
|
|
4
4
|
"description": "MCP server for Q402 — gasless USDC, USDT, and RLUSD payments across 9 EVM chains, 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": [
|