toreador_generate_qr
Generate a crypto QR code for native tokens (BTC, ETH, SOL, POL) or Solana USDC. Returns the QR data URI and on-chain payment URI free of charge.
Instructions
Generate a crypto QR code for a native token (BTC, ETH, SOL, POL) or a Solana SPL token (USDC on Solana). Returns the QR data URI (PNG base64) and the on-chain payment URI (BIP21, EIP-681, Solana Pay). FREE — no API key needed for these chains. For ERC-20 stablecoins on Ethereum/Polygon/Base (USDT, USDC, EURC), use toreador_create_session (Pro plan required).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | Token symbol. One of: BTC, ETH, SOL, POL, USDC (Solana only). | |
| chainId | Yes | Chain identifier. One of: bitcoin, ethereum, polygon, base, solana. | |
| amount | Yes | Amount as a decimal string in the token's natural unit (e.g. "0.001" for BTC, "50" for USDC). Use a string to preserve decimal precision. | |
| recipientAddress | Yes | Destination wallet address. Must match the chain (bech32 for BTC, EIP-55 for EVM, base58 for Solana). |
Implementation Reference
- src/index.ts:57-84 (schema)Tool definition / input schema for toreador_generate_qr: declares name, description, and inputSchema (token, chainId, amount, recipientAddress). Listed in FREE_TIER_TOOLS — no API key required.
{ name: "toreador_generate_qr", description: "Generate a crypto QR code for a native token (BTC, ETH, SOL, POL) or a Solana SPL token (USDC on Solana). Returns the QR data URI (PNG base64) and the on-chain payment URI (BIP21, EIP-681, Solana Pay). FREE — no API key needed for these chains. For ERC-20 stablecoins on Ethereum/Polygon/Base (USDT, USDC, EURC), use toreador_create_session (Pro plan required).", inputSchema: { type: "object", properties: { token: { type: "string", description: "Token symbol. One of: BTC, ETH, SOL, POL, USDC (Solana only).", }, chainId: { type: "string", description: "Chain identifier. One of: bitcoin, ethereum, polygon, base, solana.", }, amount: { type: "string", description: "Amount as a decimal string in the token's natural unit (e.g. \"0.001\" for BTC, \"50\" for USDC). Use a string to preserve decimal precision.", }, recipientAddress: { type: "string", description: "Destination wallet address. Must match the chain (bech32 for BTC, EIP-55 for EVM, base58 for Solana).", }, }, required: ["token", "chainId", "amount", "recipientAddress"], additionalProperties: false, }, }, - src/index.ts:204-211 (handler)Handler (dispatcher) for toreador_generate_qr: calls the Toreador public API POST /generate-qr with args.token, args.chainId, args.amount, args.recipientAddress via the toreadorRequest helper.
switch (name) { case "toreador_generate_qr": return toreadorRequest("POST", "/generate-qr", { token: args.token, chainId: args.chainId, amount: args.amount, recipientAddress: args.recipientAddress, }); - src/index.ts:237-250 (registration)Result formatting logic specific to toreador_generate_qr: when result is OK, adds a note for the LLM that qrCodeURL contains a base64 PNG data URI renderable as an image.
if (name === "toreador_generate_qr" && result.data && typeof result.data === "object") { const d = result.data as { qrCodeURL?: string }; const note = d.qrCodeURL ? "\n\nNote for the assistant: the qrCodeURL field contains a base64 PNG data URI that the user's client may render directly as an image." : ""; return { content: [ { type: "text" as const, text: JSON.stringify(result.data, null, 2) + note, }, ], }; } - src/index.ts:158-191 (helper)toreadorRequest helper: generic HTTP client used by all tool handlers, including toreador_generate_qr. Handles timeout (REQUEST_TIMEOUT_MS), JSON body, and optional API key header.
async function toreadorRequest( method: "GET" | "POST", path: string, body?: unknown, ): Promise<{ ok: boolean; status: number; data: unknown }> { const url = `${TOREADOR_BASE_URL}${path}`; const headers: Record<string, string> = { "Accept": "application/json", "User-Agent": "toreador-mcp-server/0.2.0", }; if (TOREADOR_API_KEY) headers["X-API-Key"] = TOREADOR_API_KEY; const init: RequestInit = { method, headers }; if (body !== undefined) { headers["Content-Type"] = "application/json"; init.body = JSON.stringify(body); } const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), REQUEST_TIMEOUT_MS); init.signal = ctrl.signal; try { const res = await fetch(url, init); let data: unknown = null; try { data = await res.json(); } catch { // non-JSON response — leave data as null } return { ok: res.ok, status: res.status, data }; } finally { clearTimeout(timer); } }