UNPKG

run402-mcp

Version:

MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.

109 lines • 4.82 kB
/** * Single audit surface for the optional paid-fetch dependency stack. * * Every `viem` / `@x402/*` / `mppx` import the SDK performs flows through * this file. Concentrating the imports here lets a reviewer enumerate the * SDK's direct attack surface to those packages from one place, and lets * the package.json declare them as `optionalPeerDependencies` — consumers * who never make on-chain paid requests do not need to install them. * * Adding a new import here is the only way to grow the surface; doing so * also widens what consumers must install to enable paid fetch. Keep this * list minimal. When a symbol is small enough to inline (e.g. the * `viem/chains` constants are ~5-line objects), prefer inlining over * adding a new dependency edge. */ export class PaidStackUnavailable extends Error { missingPackages; constructor(missing) { super(`run402: paid requests require optional peer dependencies that are not installed: ${missing.join(", ")}. ` + `Install them with: npm install ${missing.join(" ")}`); this.name = "PaidStackUnavailable"; this.missingPackages = missing; } } function isModuleNotFound(err) { if (!(err instanceof Error)) return false; const code = err.code; if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true; return /Cannot find (package|module)/.test(err.message); } class LoadCollector { missing = new Set(); firstOtherError = null; async load(pkg, load) { try { return await load(); } catch (err) { if (isModuleNotFound(err)) this.missing.add(pkg); else if (this.firstOtherError === null) this.firstOtherError = err; return undefined; } } throwIfFailed() { if (this.missing.size > 0) { throw new PaidStackUnavailable([...this.missing].sort()); } // eslint-disable-next-line @typescript-eslint/only-throw-error -- rethrows the import failure unchanged if (this.firstOtherError !== null) throw this.firstOtherError; } } export async function loadX402Stack() { const c = new LoadCollector(); const accounts = await c.load("viem", () => import("viem/accounts")); const viemMod = await c.load("viem", () => import("viem")); const chains = await c.load("viem", () => import("viem/chains")); const x402Fetch = await c.load("@x402/fetch", () => import("@x402/fetch")); const x402EvmClient = await c.load("@x402/evm", () => import("@x402/evm/exact/client")); const x402Evm = await c.load("@x402/evm", () => import("@x402/evm")); const offerReceipt = await c.load("@x402/extensions", () => import("@x402/extensions/offer-receipt")); c.throwIfFailed(); return { privateKeyToAccount: accounts.privateKeyToAccount, createPublicClient: viemMod.createPublicClient, http: viemMod.http, base: chains.base, baseSepolia: chains.baseSepolia, x402Client: x402Fetch.x402Client, wrapFetchWithPayment: x402Fetch.wrapFetchWithPayment, ExactEvmScheme: x402EvmClient.ExactEvmScheme, toClientEvmSigner: x402Evm.toClientEvmSigner, offerReceipt: { extractOffersFromPaymentRequired: offerReceipt.extractOffersFromPaymentRequired, decodeSignedOffers: offerReceipt.decodeSignedOffers, findAcceptsObjectFromSignedOffer: offerReceipt.findAcceptsObjectFromSignedOffer, isEIP712SignedOffer: offerReceipt.isEIP712SignedOffer, isEIP712SignedReceipt: offerReceipt.isEIP712SignedReceipt, verifyOfferSignatureEIP712: offerReceipt.verifyOfferSignatureEIP712, verifyReceiptSignatureEIP712: offerReceipt.verifyReceiptSignatureEIP712, extractReceiptFromResponse: offerReceipt.extractReceiptFromResponse, }, }; } /** The MPP challenge/credential codecs the Lightning rail needs (no Tempo, no viem). */ export async function loadLightningStack() { const c = new LoadCollector(); const mppxSpecifier = "mppx"; const mppx = await c.load("mppx", () => import(/* webpackIgnore: true */ mppxSpecifier)); c.throwIfFailed(); return { Challenge: mppx.Challenge, Credential: mppx.Credential }; } export async function loadMppStack() { const c = new LoadCollector(); const mppxSpecifier = "mppx/client"; const mppx = await c.load("mppx", () => import(/* webpackIgnore: true */ mppxSpecifier)); const accounts = await c.load("viem", () => import("viem/accounts")); c.throwIfFailed(); return { privateKeyToAccount: accounts.privateKeyToAccount, Mppx: mppx.Mppx, tempo: mppx.tempo, }; } //# sourceMappingURL=_paid-stack.js.map