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.

54 lines • 2.43 kB
/** * `vouchers` namespace — redeem a promo code into the organization's allowance. * * A promo code adds to your organization's allowance, which spends like any * other allowance: a tier purchase settles from it with no on-chain payment. * * Two properties make this safe to call from anywhere in an agent's lifecycle: * * - **Order does not matter.** Redemption works as the very first authenticated * call a brand-new wallet makes (the organization is provisioned on demand), * or long after `run402 init`. There is no init-before-redeem requirement. * - **Retrying is safe.** A repeat by the same organization returns the ORIGINAL * result with `already_redeemed: true` and never adds twice, so a call that * times out client-side can simply be re-issued. * * This namespace is deliberately thin and semantically blind: it forwards an * opaque code string to one gateway route. It does not know what a code means, * where it came from, or who issued it. Minting is not an agent operation — * it needs a registered issuer key that no tenant holds. */ import { assertNonEmptyString } from "../validation.js"; export class Vouchers { client; /** Alias of {@link redeem}. */ redeemCode; constructor(client) { this.client = client; this.redeemCode = this.redeem.bind(this); } /** * Redeem a promo code into the authenticated wallet's organization. * * The code is sent verbatim — the gateway owns the grammar and is forgiving * about it (case-insensitive, hyphens optional, and the Crockford * confusables `O`→`0` / `I`,`L`→`1` are mapped), so a client-side format * check would only invent ways to reject a code the server would have * accepted. * * Requires wallet (SIWX) auth. Errors carry the canonical envelope: * `VOUCHER_NOT_FOUND` (404 — unknown *or* malformed, deliberately * indistinguishable), `VOUCHER_EXPIRED` (410), `VOUCHER_ALREADY_REDEEMED` * (409 — a different organization got there first), `PROMO_LIMIT_REACHED` * (403), `RATE_LIMITED` (429). */ async redeem(code) { assertNonEmptyString(code, "code", "redeeming a promo code"); return this.client.request("/vouchers/v1/redemptions", { method: "POST", body: { code }, context: "redeeming a promo code", }); } } //# sourceMappingURL=vouchers.js.map