diff --git a/.env.example b/.env.example index dcd6a48..0ac03b3 100644 --- a/.env.example +++ b/.env.example @@ -66,3 +66,26 @@ LINK_TOKEN_ENCRYPTION_KEY= # Exact trusted checkout/frame origins per approved merchant (JSON object). LINK_CHECKOUT_ORIGINS={} + +# Optional Crossmint Agent Checkouts. Buy at any store with the person's own card. See docs/crossmint.md. +# Production server key (sk_) with agent-checkouts.* scopes. Leave unset to keep the tools disabled. +CROSSMINT_SERVER_API_KEY= +CROSSMINT_USER_ID= +# Optional per-checkout ceiling ("50.00 EUR") and exact merchant origins. +CROSSMINT_MAX_COST= +CROSSMINT_ALLOWED_MERCHANTS= +# Set up in Bell at /crossmint/setup (operator only): the saved delivery details and the approved budget. +CROSSMINT_BUYER_PROFILE_ID= +# The budget (order intent) Bell pays with. Required only to pay; never shown to the model. +CROSSMINT_ORDER_INTENT_ID= +# For the setup page: client key (ck_) with payment-methods.* and order-intents.* scopes, the project id, +# and a base64 PEM RSA key that signs the operator token Crossmint checks at /api/crossmint/jwks. +CROSSMINT_CLIENT_API_KEY= +CROSSMINT_PROJECT_ID= +CROSSMINT_JWT_PRIVATE_KEY= +# Optional Crossmint Agent Cards: pay in this conversation's browser with a one-time card. Set to 1 to +# turn it on. Needs LINK_SANDBOX=0, DATABASE_URL, the setup keys above, and a budget whose Visa or +# Mastercard rail is verified. +CROSSMINT_CARD_CHECKOUT= +# Exact payment-frame origins per merchant origin (JSON object). +CROSSMINT_CHECKOUT_ORIGINS={} diff --git a/README.md b/README.md index f7457b7..2043738 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ pnpm dev | Link by Stripe | Wallet authorization, spend approval, and checkout through Linq | [Sandbox and wallet setup](docs/link.md) | | 1Password | Operator credentials and OTP; personal Agentic Autofill is disabled by default | [Operator access](docs/browser-runtime.md#credentials-and-otp) · [Personal access status](docs/onepassword.md) | | Baselayer | Verified access to approved merchants using short-lived credentials | [Merchant access](docs/baselayer.md) | +| Crossmint | Buy at any store with the person's own card, worldwide, under a spending cap the person approves on Bell's setup page; or pay in Bell's browser with a one-time agent card | [Agent checkouts and agent cards](docs/crossmint.md) | See the [repository layout and implementation map](docs/repository.md) to extend Bell. diff --git a/agent/instructions.md b/agent/instructions.md index 56ea2dc..6427bd3 100644 --- a/agent/instructions.md +++ b/agent/instructions.md @@ -38,3 +38,26 @@ navigation needs a fresh proof. After access, call snapshot and screenshot to ve Do not claim a successful mint or merchant access unless the tool result confirms it. For private Linq senders, use `onepassword_connect`, `onepassword_status`, `onepassword_login`, and `onepassword_disconnect` for personal 1Password access. If status is disabled, explain that personal 1Password login is not available yet; do not offer a consent link or fall back to the operator vault. Never use the operator vault tools for a messaging sender. Connecting is separate from approving a website login. Use the exact login URL and a distinct expected success path on the same origin. A verified destination is not proof of account identity. The first version supports single-step sign-in only. Approval links are sent through Eve authorization; do not ask for tokens, integration keys, passwords, or OTPs in chat. If a private fill fails, start a new conversation rather than inspecting the blocked browser. Personal browser mode does not support reusable Contexts. + +Use crossmint_checkout when Crossmint Agent Checkouts is configured and the user wants a purchase +completed by Crossmint rather than in this conversation's browser. It works at any store, pays with +the user's own card, and the card number never reaches you. Start with the product URL, the request, +and the user's spending cap. The checkout runs in Crossmint's browser, so this conversation's browser +stays idle. While it runs, each result can carry progress: tell the user in one short sentence what +Crossmint is doing, in your own words and without ids, then call crossmint_checkout status again. Do +not repeat a stage you already reported. Answer form questions from what the user said, using option +values for choice fields, and never fill protected fields. At a payment request, call crossmint_pay +with the amount, currency, merchant, and merchant name copied from the request. Eve asks the person to approve, and the +server verifies those values against Crossmint before paying. Call crossmint_checkout decline if the +person says no. Only a succeeded result with purchase.kind receipt_captured is a placed order. Report +any other outcome as what it is. Never start a second checkout for the same request while one is +unresolved, and never ask for or print API keys or order intent ids. + +Use crossmint_card_checkout when Crossmint Agent Cards is configured and the user wants to pay in +this conversation's browser with their own card. Confirm the merchant, items, delivery details, +currency, and final total, and fill everything but the card first, billing address included. Then +call it with the exact total, currency, the checkout page's URL or host, exact CSS selectors for the +card number, CVC, and expiry, and the pay button. Eve asks the person to approve. The server checks +the order intent, mints a one-time card, fills it, and presses pay once; card values never reach +you. Its statuses do not prove payment, and the browser stays private afterwards, so check the order +through human handoff. Never retry an uncertain purchase. Report refusal reasons as they are. diff --git a/agent/lib/crossmint.ts b/agent/lib/crossmint.ts new file mode 100644 index 0000000..f5eacc5 --- /dev/null +++ b/agent/lib/crossmint.ts @@ -0,0 +1,57 @@ +import type { ApprovalResponseContext, ApprovalResponseDecision } from "eve/tools/approval"; +import { z } from "zod"; +import { + AMOUNT, + CrossmintPolicyError, + CrossmintRequestError, + CrossmintSetupError, + isCrossmintConfigured, + type CheckoutSnapshot, +} from "../../server/crossmint/client"; +import { hostOf } from "../../server/crossmint/payment"; + +/** How long one tool call waits for Crossmint before returning the latest snapshot. */ +export const WAIT_MS = 90_000; +/** After starting a run, return at the first progress so the person hears back within seconds. */ +export const FIRST_UPDATE_MS = 25_000; +/** While a run works, return at most this late, and no sooner than MIN_UPDATE_MS unless it settles. */ +export const UPDATE_MS = 60_000; +export const MIN_UPDATE_MS = 15_000; + +export const amount = z.string().regex(AMOUNT, "Decimal string such as 20.00"); +export const currency = z.string().length(3).toUpperCase().describe("ISO 4217 code, such as USD or EUR."); +export const runId = z.string().min(1).max(200); +export const requestId = z.string().min(1).max(200); + +export type CheckoutToolOutput = + | { status: "not_configured"; hint: string } + | { status: "error"; reason: string; message: string } + | CheckoutSnapshot; + +export function notConfigured(): CheckoutToolOutput | undefined { + if (isCrossmintConfigured()) return undefined; + return { status: "not_configured", hint: "Set CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID on the server. See docs/crossmint.md." }; +} + +/** "Zara (payments.zara.com)" or just the host: the approval names who is paid in plain words. */ +export function payee(input: { merchant: string; merchantName?: string }): string { + const host = hostOf(input.merchant) ?? input.merchant; + const name = input.merchantName?.trim(); + return name && name.toLowerCase() !== host ? `${name} (${host})` : host; +} + +/** Approval response policy for payments: only the authenticated sender who asked can approve. */ +export function requesterOnly({ request, response }: Pick, "request" | "response">): ApprovalResponseDecision { + const requester = request.principal; + if (!requester) return { status: "rejected", reason: "Payments need an authenticated sender." }; + const same = response.principal.principalId === requester.principalId && response.principal.authenticator === requester.authenticator; + return same ? { status: "allowed" } : { status: "rejected", reason: "Only the person who requested this payment can approve it." }; +} + +/** Crossmint errors carry fixed, sanitized messages the model may see. Anything else is rethrown. */ +export function errorOutput(error: unknown): CheckoutToolOutput { + if (error instanceof CrossmintSetupError || error instanceof CrossmintRequestError || error instanceof CrossmintPolicyError) { + return { status: "error", reason: error.reason, message: error.message }; + } + throw error; +} diff --git a/agent/tools/crossmint_card_checkout.ts b/agent/tools/crossmint_card_checkout.ts new file mode 100644 index 0000000..29ba58f --- /dev/null +++ b/agent/tools/crossmint_card_checkout.ts @@ -0,0 +1,120 @@ +import { defineTool, toolOutput } from "eve/tools"; +import { always } from "eve/tools/approval"; +import { z } from "zod"; +import { amount, currency, errorOutput, payee, requesterOnly, type CheckoutToolOutput } from "../lib/crossmint"; +import { runBrowserOperation, runCancelableBrowserWork } from "../lib/browser-runtime"; +import { assertCheckoutPolicy } from "../../server/crossmint/client"; +import { + assertCardPayment, + cardConfig, + checkoutAmount, + CrossmintCardError, + getOrderIntent, + idempotencyKey, + isCrossmintCardsConfigured, + merchantOrigin, + mintCard, + paymentOrigins, +} from "../../server/crossmint/cards"; +import { hasBrowserPrivacyLock } from "../../server/browser/privacy-lock"; +import { checkoutInHostedPage } from "../../server/link/checkout-browser"; +import { checkoutInput } from "../../server/link/payment"; + +const cardTarget = checkoutInput.shape.fields.element.extend({ field: z.enum(["number", "cvc", "exp_month", "exp_year", "expiry"]) }); + +const inputSchema = z.object({ + amount: amount.describe("The exact total on the merchant's checkout, including tax and shipping."), + currency, + merchant: z.string().min(1).max(255).describe("The checkout page's URL or host."), + fields: z + .array(cardTarget) + .min(1) + .max(16) + .describe("Exact CSS selectors for the card inputs: number, cvc, and expiry (MM/YY) or exp_month (MM) and exp_year (YYYY). Add a frame selector for a card iframe."), + submit: checkoutInput.shape.submit.describe("The pay button."), + confirmation: checkoutInput.shape.submit.optional().describe("An element that appears only once the merchant confirms the order."), +}); + +type Input = z.infer; + +type CardCheckoutOutput = + | CheckoutToolOutput + | { status: "payment_not_configured"; hint: string } + | { status: "submission_attempted" | "merchant_confirmation_observed" | "outcome_unknown"; verify_payment: true } + | { status: "waiting_for_user"; reason: string; action: string }; + +export default defineTool({ + description: + "Pay at the merchant checkout open in this conversation's browser with the person's Crossmint agent card. First complete everything but the card and stay on the payment step. Supply the exact total and currency, the checkout page's URL or host, exact CSS selectors for the card inputs, and the pay button. Eve stops and asks the person to approve the amount and merchant. The server then checks the order intent the person approved in Crossmint (status, merchant, currency, remaining amount, expiry, verified card rail), mints a one-time card on Visa Intelligent Commerce or Mastercard Agent Pay, fills it, and presses pay once. The card number never reaches this assistant, and the browser stays private afterwards. submission_attempted, merchant_confirmation_observed, and outcome_unknown do not prove payment; check the order through human handoff. Call once per purchase and never retry an uncertain one.", + inputSchema, + label: { + start: (input: Readonly) => `Paying ${input.amount} ${input.currency} at ${payee(input)} with a Crossmint agent card`, + }, + approval: { + request: always(), + prompt: ({ input }) => `Pay ${input.amount} ${input.currency} at ${payee(input)} with your Crossmint agent card?`, + response: requesterOnly, + }, + async execute(input, ctx): Promise { + ctx.abortSignal.throwIfAborted(); + if (!isCrossmintCardsConfigured()) { + return { status: "not_configured", hint: "Set the Crossmint Agent Cards settings on the server. See docs/crossmint.md." }; + } + if (!ctx.session.auth.current) { + return { status: "error", reason: "authentication_required", message: "Payments are available to authenticated senders only. The anonymous web demo cannot pay." }; + } + const signal = ctx.abortSignal; + let minted = false; + try { + const config = cardConfig(); + if (!config.orderIntentId) { + return { status: "payment_not_configured", hint: "No order intent is configured on the server, so Bell cannot pay. Tell the person. See docs/crossmint.md." }; + } + const payment = { amount: input.amount, currency: input.currency }; + const origin = merchantOrigin(input.merchant); + assertCheckoutPolicy(origin, payment, config); + const { provider } = assertCardPayment(await getOrderIntent({ config, signal }), { ...payment, merchant: origin }); + const checkout = checkoutInput.parse({ + id: "crossmint_card", + amount: checkoutAmount(input.amount, input.currency), + currency: input.currency.toLowerCase(), + credential: "card", + fields: input.fields, + submit: input.submit, + ...(input.confirmation ? { confirmation: input.confirmation } : {}), + }); + const key = idempotencyKey(ctx.session.id, ctx.callId); + // A mint spends its amount at once, so it happens only while the browser lock is held, which + // lets the fill quarantine the browser right after. + const mint = async () => { + if (!hasBrowserPrivacyLock()) throw new CrossmintCardError("browser_lock_unavailable"); + const card = await mintCard(provider, payment, key, { config, signal }); + minted = true; + return card; + }; + // The card is minted inside the fill, after every target and origin check, and never leaves it. + const output = await runCancelableBrowserWork(ctx.session.id, signal, () => + runBrowserOperation(ctx.session.id, (browser) => + browser.withHostedPage(signal, (page, connection) => + checkoutInHostedPage(page, connection, checkout, paymentOrigins(config, origin), mint, signal), true))); + const result: { status: string; reason?: string; action?: string } = output.result; + if (result.status === "waiting_for_user") return { status: "waiting_for_user", reason: result.reason ?? "captcha", action: result.action ?? "" }; + return { status: result.status as "submission_attempted" | "merchant_confirmation_observed" | "outcome_unknown", verify_payment: true }; + } catch (error) { + if (error instanceof CrossmintCardError) return { status: "error", reason: error.reason, message: error.message }; + if (!signal.aborted && error instanceof Error && error.message.startsWith("Checkout stopped before submission.")) { + return { + status: "error", + reason: "stopped_before_submission", + message: "The checkout stopped after the card was issued and before it was submitted. The browser is now private. Check the merchant page through human handoff and do not retry.", + }; + } + // Any other failure after the mint: the amount is spent, so a retry must not issue a second card. + if (minted) return { status: "error", reason: "card_issued_unfinished", message: new CrossmintCardError("card_issued_unfinished").message }; + return errorOutput(error); + } + }, + toModelOutput(output) { + return toolOutput.json(output); + }, +}); diff --git a/agent/tools/crossmint_checkout.ts b/agent/tools/crossmint_checkout.ts new file mode 100644 index 0000000..7fa5898 --- /dev/null +++ b/agent/tools/crossmint_checkout.ts @@ -0,0 +1,115 @@ +import { defineTool, toolOutput } from "eve/tools"; +import { z } from "zod"; +import { + amount, + currency, + errorOutput, + FIRST_UPDATE_MS, + MIN_UPDATE_MS, + notConfigured, + requestId, + runId, + UPDATE_MS, + type CheckoutToolOutput, +} from "../lib/crossmint"; +import { + answerForm, + cancelCheckout, + createCheckout, + declineRequest, + getCheckout, + waitForCheckout, + type CheckoutSnapshot, + type WaitOptions, +} from "../../server/crossmint/client"; +import { assertSessionCheckout, rememberCheckout, type CheckoutRecord } from "../../server/crossmint/runs"; + +/** Wait for the next step or, while the run works, the next new stage, and remember what was reported. */ +async function nextUpdate(record: CheckoutRecord, options: WaitOptions): Promise { + const snapshot = await waitForCheckout(record.runId, { progressSince: record.lastStage ?? null, ...options }); + if (snapshot.progress) record.lastStage = snapshot.progress.stage; + return snapshot; +} + +const inputSchema = z.discriminatedUnion("action", [ + z.object({ + action: z.literal("start"), + startUrl: z.string().url().max(2048).describe("Product or store page to start from."), + task: z.string().min(1).max(20_000).describe("What to buy, in plain language. Item, options, quantity, delivery."), + maxCost: z.object({ amount: amount.describe("Spending cap including shipping and tax."), currency }), + merchantGuidance: z.string().min(1).max(20_000).optional().describe("Optional notes about this merchant's checkout."), + countryCode: z.string().length(2).toUpperCase().optional().describe("Optional browser location for the checkout, such as ES or US."), + }), + z.object({ action: z.literal("status"), runId }), + z.object({ + action: z.literal("answer"), + runId, + requestId, + answers: z + .record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.string())])) + .describe("One value per form field key. For a choice field, an option value. Protected fields cannot be answered here."), + }), + z.object({ action: z.literal("decline"), runId, requestId }), + z.object({ action: z.literal("cancel"), runId }), +]); + +export default defineTool({ + description: + "Buy at any store through Crossmint Agent Checkouts under a hard spending cap. Crossmint picks the fastest path for the store, the merchant API, an agent protocol, or its own checkout browser, so nothing runs in this conversation's browser. The person pays with their own card, worldwide, and the card number never reaches this assistant. Call start with the product URL, a plain-language task, and maxCost, then follow requiredAction. For a form, call answer with one value per field key. For a payment, call crossmint_pay. decline refuses a request and cancel stops the run. Each call returns a status snapshot: start returns within about twenty-five seconds, and status waits for the next step or, while the run works, the next progress stage, up to a minute. When the snapshot carries progress, tell the person in one short sentence what Crossmint is doing, then call status again. A succeeded result with purchase.kind receipt_captured is the only proof of a placed order. Never start a second checkout for the same request while one is unresolved.", + inputSchema, + label: { + start: (input) => + input.action === "start" ? `Starting a Crossmint checkout at ${new URL(input.startUrl).hostname}` : `Crossmint checkout: ${input.action}`, + }, + async execute(input, ctx): Promise { + ctx.abortSignal.throwIfAborted(); + const unavailable = notConfigured(); + if (unavailable) return unavailable; + const sessionId = ctx.session.id; + const signal = ctx.abortSignal; + try { + switch (input.action) { + case "start": { + const { runId } = await createCheckout(input, { signal }); + const record = { runId, maxCost: input.maxCost, principalId: ctx.session.auth.current?.principalId ?? null }; + rememberCheckout(sessionId, record); + return await nextUpdate(record, { signal, timeoutMs: FIRST_UPDATE_MS }); + } + case "status": + return await nextUpdate(assertSessionCheckout(sessionId, input.runId), { signal, timeoutMs: UPDATE_MS, minProgressMs: MIN_UPDATE_MS }); + case "answer": { + const record = assertSessionCheckout(sessionId, input.runId); + const current = await getCheckout(input.runId, { signal }); + const action = current.requiredAction; + if (!action || action.requestId !== input.requestId) return current; + if (action.interaction.kind !== "form") { + return { status: "error", reason: "wrong_interaction", message: "This request is not a form. Payment requests go through crossmint_pay." }; + } + const protectedKeys = new Set(action.interaction.fields.filter((field) => field.handling === "protected").map((field) => field.key)); + if (Object.keys(input.answers).some((key) => protectedKeys.has(key))) { + return { + status: "error", + reason: "protected_field", + message: "Protected fields (codes, passwords, card data) cannot be answered through the model. Decline the request or ask the person to finish in Crossmint's hosted flow.", + }; + } + await answerForm(input.runId, input.requestId, input.answers, { signal }); + return await nextUpdate(record, { signal, timeoutMs: UPDATE_MS, minProgressMs: MIN_UPDATE_MS, skipRequestId: input.requestId }); + } + case "decline": + assertSessionCheckout(sessionId, input.runId); + await declineRequest(input.runId, input.requestId, { signal }); + return await waitForCheckout(input.runId, { signal, timeoutMs: 30_000, skipRequestId: input.requestId }); + case "cancel": + assertSessionCheckout(sessionId, input.runId); + await cancelCheckout(input.runId, { signal }); + return await waitForCheckout(input.runId, { signal, timeoutMs: 30_000 }); + } + } catch (error) { + return errorOutput(error); + } + }, + toModelOutput(output) { + return toolOutput.json(output); + }, +}); diff --git a/agent/tools/crossmint_pay.ts b/agent/tools/crossmint_pay.ts new file mode 100644 index 0000000..d087ff1 --- /dev/null +++ b/agent/tools/crossmint_pay.ts @@ -0,0 +1,71 @@ +import { defineTool, toolOutput } from "eve/tools"; +import { always } from "eve/tools/approval"; +import { z } from "zod"; +import { amount, currency, errorOutput, notConfigured, payee, requestId, requesterOnly, runId, WAIT_MS, type CheckoutToolOutput } from "../lib/crossmint"; +import { CrossmintSetupError, getCheckout, payWithOrderIntent, waitForCheckout } from "../../server/crossmint/client"; +import { assertPaymentMatches, PaymentMismatchError } from "../../server/crossmint/payment"; +import { assertSessionCheckout } from "../../server/crossmint/runs"; + +const inputSchema = z.object({ + runId, + requestId: requestId.describe("The open payment request's id."), + amount: amount.describe("The exact total Crossmint is asking for, copied from the payment request."), + currency, + merchant: z.string().min(1).max(255).describe("The merchant URL or host from the payment request."), + merchantName: z.string().min(1).max(120).optional().describe("The merchant's name from the payment request, when it has one."), +}); + +type Input = z.infer; + +type PayOutput = CheckoutToolOutput | { status: "payment_not_configured"; runId: string; requestId: string; hint: string }; + +export default defineTool({ + description: + "Pay the open payment request of a Crossmint checkout with the person's own card, through the order intent held on the server. Copy amount, currency, and merchant exactly from the payment request, and its merchant name when it has one. Eve stops and asks the person to approve this call. The server then compares those three values with the live request and with the cap the run started with, and refuses on any difference. The card number never reaches this assistant. Needs an authenticated sender. Call once per payment request. Use crossmint_checkout decline if the person says no.", + inputSchema, + label: { + start: (input: Readonly) => `Paying ${input.amount} ${input.currency} at ${payee(input)} through Crossmint`, + }, + approval: { + request: always(), + prompt: ({ input }) => `Pay ${input.amount} ${input.currency} at ${payee(input)} with your saved card?`, + response: requesterOnly, + }, + async execute(input, ctx): Promise { + ctx.abortSignal.throwIfAborted(); + const unavailable = notConfigured(); + if (unavailable) return unavailable; + const auth = ctx.session.auth.current; + if (!auth) { + return { status: "error", reason: "authentication_required", message: "Payments are available to authenticated senders only. The anonymous web demo cannot pay." }; + } + const signal = ctx.abortSignal; + try { + const record = assertSessionCheckout(ctx.session.id, input.runId); + if (record.principalId !== null && record.principalId !== auth.principalId) { + return { status: "error", reason: "principal_mismatch", message: "A different sender started this checkout." }; + } + try { + assertPaymentMatches(input, await getCheckout(input.runId, { signal }), record); + await payWithOrderIntent(input.runId, input.requestId, { signal }); + } catch (error) { + if (error instanceof PaymentMismatchError) return { status: "error", reason: error.reason, message: error.message }; + if (error instanceof CrossmintSetupError && error.setting === "CROSSMINT_ORDER_INTENT_ID") { + return { + status: "payment_not_configured", + runId: input.runId, + requestId: input.requestId, + hint: "No order intent is configured on the server, so Bell cannot pay. Decline the request and tell the person. See docs/crossmint.md.", + }; + } + throw error; + } + return await waitForCheckout(input.runId, { signal, timeoutMs: WAIT_MS, skipRequestId: input.requestId }); + } catch (error) { + return errorOutput(error); + } + }, + toModelOutput(output) { + return toolOutput.json(output); + }, +}); diff --git a/app/api/crossmint/jwks/route.ts b/app/api/crossmint/jwks/route.ts new file mode 100644 index 0000000..6d9636e --- /dev/null +++ b/app/api/crossmint/jwks/route.ts @@ -0,0 +1,15 @@ +import { operatorJwks, parseRsaPrivateKey } from "../../../../server/crossmint/operator-jwt"; + +export const runtime = "nodejs"; +export const dynamic = "force-dynamic"; + +const headers = { "cache-control": "no-store", "x-content-type-options": "nosniff" }; + +// Public by design: Crossmint fetches this to check the operator JWTs Bell signs. +export function GET() { + const configured = process.env.CROSSMINT_JWT_PRIVATE_KEY?.trim(); + if (!configured) return new Response("Not found.", { status: 404, headers }); + const key = parseRsaPrivateKey(configured); + if (!key) return new Response("Check CROSSMINT_JWT_PRIVATE_KEY in the server configuration.", { status: 500, headers }); + return Response.json(operatorJwks(key), { headers: { ...headers, "cache-control": "public, max-age=300" } }); +} diff --git a/app/crossmint/setup/actions.ts b/app/crossmint/setup/actions.ts new file mode 100644 index 0000000..16a5ca8 --- /dev/null +++ b/app/crossmint/setup/actions.ts @@ -0,0 +1,143 @@ +"use server"; + +import { routeAuth } from "eve/channels/auth"; +import { headers } from "next/headers"; +import { z } from "zod"; +import { isCrossmintCardsConfigured } from "../../../server/crossmint/cards"; +import { AMOUNT, createBuyerProfile, CrossmintRequestError, CrossmintSetupError } from "../../../server/crossmint/client"; +import { + cancelOrderIntent, + createOrderIntent, + CrossmintOperatorError, + getRegistration, + operatorConfig, + registerCard, +} from "../../../server/crossmint/operator"; +import { operatorJwt } from "../../../server/crossmint/operator-jwt"; +import { operatorAuth } from "../../../server/operator-auth"; +import { budgetView, type Budget, type ProfileView, profileView } from "./view"; + +export type ActionResult = ({ ok: true } & T) | { ok: false; message: string }; + +/** + * The proxy already asked for the operator's credentials; every action checks them again, as the + * POST it is, so the same-origin guard for writes runs here too. + */ +async function requireOperator(): Promise { + const incoming = await headers(); + const host = incoming.get("x-forwarded-host") ?? incoming.get("host") ?? "localhost"; + const protocol = incoming.get("x-forwarded-proto") ?? "http"; + const request = new Request(`${protocol}://${host}/crossmint/setup`, { method: "POST", headers: incoming }); + const auth = await routeAuth(request, [operatorAuth]); + if (auth instanceof Response) throw new Error("Sign in as the Bell operator."); +} + +/** Operator-facing messages. Crossmint's own message is kept when it names the fix. */ +function failure(error: unknown): { ok: false; message: string } { + if (error instanceof CrossmintOperatorError) { + return { ok: false, message: error.detail ? `${error.message} Crossmint says: ${error.detail}` : error.message }; + } + if (error instanceof CrossmintSetupError || error instanceof CrossmintRequestError) return { ok: false, message: error.message }; + if (error instanceof z.ZodError) return { ok: false, message: error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ") }; + throw error; +} + +/** A fresh ten-minute operator token for Crossmint's card form. */ +export async function refreshToken(): Promise> { + await requireOperator(); + try { + return { ok: true, jwt: operatorJwt(operatorConfig()) }; + } catch (error) { + return failure(error); + } +} + +const country = z.string().trim().regex(/^[A-Za-z]{2}$/, "two-letter country code").transform((value) => value.toUpperCase()); + +const profileInput = z.object({ + first: z.string().trim().min(1).max(100), + last: z.string().trim().min(1).max(100), + email: z.string().trim().email().max(254), + phone: z.string().trim().min(5).max(40), + street: z.string().trim().min(1).max(200), + street2: z.string().trim().max(200).optional(), + postalCode: z.string().trim().min(1).max(40), + locality: z.string().trim().min(1).max(120), + region: z.string().trim().max(10).optional(), + countryCode: country, +}); + +/** Save the delivery details checkouts use instead of asking. No payment data is stored. */ +export async function saveBuyerProfile(input: z.input): Promise> { + await requireOperator(); + try { + const value = profileInput.parse(input); + const saved = await createBuyerProfile({ + label: "Bell", + name: { first: value.first, last: value.last }, + contact: { email: value.email, phone: value.phone }, + shipping: { + addressLines: [value.street, value.street2].filter((line): line is string => Boolean(line)), + locality: value.locality, + countryCode: value.countryCode, + administrativeAreaCode: value.region ? value.region.toUpperCase() : null, + postalCode: value.postalCode, + }, + }); + return { ok: true, id: saved.id, profile: profileView(saved) }; + } catch (error) { + return failure(error); + } +} + +const budgetInput = z.object({ + paymentMethodId: z.string().min(1).max(200), + /** One per draft, so a repeated or retried approval never creates a second budget. */ + idempotencyKey: z.string().regex(/^[A-Za-z0-9-]{16,64}$/), + amount: z.string().regex(AMOUNT, "decimal amount such as 30.00"), + currency: z.string().trim().regex(/^[A-Za-z]{3}$/, "three-letter currency code").transform((value) => value.toUpperCase()), + days: z.coerce.number().int().min(1).max(365), + description: z.string().trim().min(1).max(200), + merchant: z.object({ + name: z.string().trim().min(1).max(200), + url: z.string().trim().url().refine((value) => value.startsWith("https://"), "an HTTPS URL"), + countryCode: country, + }), + consumer: z.object({ email: z.string().trim().email(), countryCode: country, languageCode: z.string().trim().min(2).max(35) }), +}); + +/** + * Register the saved card with the person's email, then approve the budget. Crossmint refuses an + * empty registration, and Crossmint's card component sends one, so Bell registers first. + */ +export async function approveBudget(input: z.input): Promise> { + await requireOperator(); + try { + const value = budgetInput.parse(input); + const registration = await getRegistration(value.paymentMethodId); + if (!registration || !registration.rails.some((rail) => rail.status === "enabled")) { + await registerCard(value.paymentMethodId, value.consumer); + } + const intent = await createOrderIntent({ + paymentMethodId: value.paymentMethodId, + amount: { value: value.amount, currency: value.currency }, + merchant: value.merchant, + description: value.description, + expiresAt: new Date(Date.now() + value.days * 86_400_000).toISOString(), + }, { idempotencyKey: `bell-budget-${value.idempotencyKey}` }); + return { ok: true, budget: budgetView(intent, process.env.CROSSMINT_ORDER_INTENT_ID?.trim(), undefined, isCrossmintCardsConfigured()) }; + } catch (error) { + return failure(error); + } +} + +/** Cancel a budget. Nothing more can be spent from it. */ +export async function cancelBudget(orderIntentId: string): Promise> { + await requireOperator(); + try { + await cancelOrderIntent(z.string().min(1).max(200).parse(orderIntentId)); + return { ok: true }; + } catch (error) { + return failure(error); + } +} diff --git a/app/crossmint/setup/crossmint-logo.svg b/app/crossmint/setup/crossmint-logo.svg new file mode 100644 index 0000000..a86ea1a --- /dev/null +++ b/app/crossmint/setup/crossmint-logo.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/crossmint/setup/page.tsx b/app/crossmint/setup/page.tsx new file mode 100644 index 0000000..4397d24 --- /dev/null +++ b/app/crossmint/setup/page.tsx @@ -0,0 +1,84 @@ +import { routeAuth } from "eve/channels/auth"; +import type { Metadata } from "next"; +import { headers } from "next/headers"; +import { crossmintConfig, CrossmintSetupError, getBuyerProfile, isCrossmintConfigured } from "../../../server/crossmint/client"; +import { isCrossmintCardsConfigured } from "../../../server/crossmint/cards"; +import { CrossmintOperatorError, listOrderIntents, operatorConfig, type OperatorConfig } from "../../../server/crossmint/operator"; +import { operatorAuth } from "../../../server/operator-auth"; +import Setup, { type Check, type SetupProps } from "./setup"; +import { budgetView, profileView } from "./view"; + +export const dynamic = "force-dynamic"; +export const metadata: Metadata = { title: "Payments setup | Bell" }; + +const message = (error: unknown) => (error instanceof Error ? error.message : "Unexpected error."); + +// Operator only. proxy.ts asks for the credentials; this checks again before signing a token. +export default async function CrossmintSetupPage() { + const incoming = await headers(); + const host = incoming.get("x-forwarded-host") ?? incoming.get("host") ?? "localhost"; + const protocol = incoming.get("x-forwarded-proto") ?? "http"; + const auth = await routeAuth(new Request(`${protocol}://${host}/crossmint/setup`, { headers: incoming }), [operatorAuth]); + if (auth instanceof Response) { + return

Sign in as the Bell operator to set up payments.

; + } + + const props: SetupProps = { + checks: { server: { state: "todo", text: "" }, operator: { state: "todo", text: "" }, token: { state: "todo", text: "" } }, + budgets: [], + defaults: {}, + configured: { profile: Boolean(process.env.CROSSMINT_BUYER_PROFILE_ID?.trim()), orderIntent: Boolean(process.env.CROSSMINT_ORDER_INTENT_ID?.trim()) }, + }; + + // 1. The server key runs checkouts. + let serverReady = false; + try { + if (!isCrossmintConfigured()) throw new CrossmintSetupError("missing_configuration", "CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID"); + crossmintConfig(); + serverReady = true; + props.checks.server = { state: "ok", text: "Server key and operator id are set." }; + } catch (error) { + props.checks.server = { state: "error", text: message(error) } satisfies Check; + } + + // 2. The client key and Bell's operator token approve budgets. + let config: OperatorConfig | undefined; + try { + config = operatorConfig(); + props.checks.operator = { state: "ok", text: "Client key, project id, and signing key are set." }; + const loopback = new URL(config.origin).protocol === "http:"; + props.jwks = { url: `${config.origin}/api/crossmint/jwks`, issuer: config.projectId, loopback }; + } catch (error) { + props.checks.operator = { state: serverReady ? "error" : "todo", text: message(error) }; + } + + // 3. Crossmint accepts Bell's token: listing budgets proves it. + if (config) { + try { + const configured = process.env.CROSSMINT_ORDER_INTENT_ID?.trim(); + const cards = isCrossmintCardsConfigured(); + props.budgets = (await listOrderIntents({ config })).map((intent) => budgetView(intent, configured, undefined, cards)); + props.checks.token = { state: "ok", text: "Crossmint accepts Bell's operator token." }; + props.apiKey = config.clientApiKey; + } catch (error) { + props.checks.token = + error instanceof CrossmintOperatorError && error.reason === "unauthorized" + ? { state: "error", text: "Crossmint rejected Bell's operator token. Point the project's custom JWT settings at Bell below." } + : { state: "error", text: message(error) }; + } + } + + // Delivery details, read with the server key. + const profileId = process.env.CROSSMINT_BUYER_PROFILE_ID?.trim(); + if (serverReady && profileId) { + try { + const profile = profileView(await getBuyerProfile(profileId)); + props.profile = profile; + props.defaults = { email: profile.email, countryCode: profile.countryCode }; + } catch (error) { + props.profileError = `CROSSMINT_BUYER_PROFILE_ID: ${message(error)}`; + } + } + + return ; +} diff --git a/app/crossmint/setup/setup.module.css b/app/crossmint/setup/setup.module.css new file mode 100644 index 0000000..1d0610d --- /dev/null +++ b/app/crossmint/setup/setup.module.css @@ -0,0 +1,525 @@ +/* Crossmint styling for the operator setup page. Bell's global stylesheet targets bare elements, + so every element here carries a class, which wins over those rules. */ +.page { + --xm-green: #00c768; + --xm-green-dark: #00a846; + --xm-dark: #0a1825; + --xm-grey-bg: #f9fafa; + --xm-grey-mid: #e5e7eb; + --xm-grey-text: #6b7280; + --xm-tint: #e8f8ef; + --xm-tint-soft: #f5fbf8; + --xm-amber: #b45309; + --xm-amber-bg: #fef3c7; + --xm-red: #dc2626; + --xm-red-bg: #fef2f2; + --xm-font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + min-height: 100vh; + background: var(--xm-grey-bg); + color: var(--xm-dark); + font-family: var(--xm-font); + font-size: 15px; + line-height: 1.55; +} + +.shell { + max-width: 920px; + margin: 0 auto; + padding: 28px 24px 64px; +} + +.top { + display: flex; + align-items: center; + gap: 14px; + margin: 0 0 40px; +} + +.divider { + width: 1px; + height: 22px; + background: var(--xm-grey-mid); +} + +.product { + font-weight: 600; + font-size: 16px; +} + +.spacer { + flex: 1; +} + +.operator { + font-size: 12px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + color: var(--xm-grey-text); + border: 1px solid var(--xm-grey-mid); + border-radius: 999px; + padding: 4px 10px; + background: #fff; +} + +.hero { + margin: 0 0 28px; +} + +.h1 { + font-size: 40px; + line-height: 1.1; + letter-spacing: -0.02em; + font-weight: 700; + margin: 0 0 10px; +} + +.heroText { + max-width: 620px; + margin: 0; + color: var(--xm-grey-text); + font-size: 17px; +} + +.card { + background: #fff; + border: 1px solid var(--xm-grey-mid); + border-radius: 12px; + margin: 0 0 18px; + box-shadow: 0 1px 2px rgba(10, 24, 37, 0.04); +} + +.cardHead { + display: flex; + align-items: center; + gap: 12px; + padding: 20px 24px; + border-bottom: 1px solid var(--xm-grey-mid); +} + +.number { + display: grid; + place-items: center; + width: 28px; + height: 28px; + border-radius: 999px; + background: var(--xm-tint); + color: var(--xm-green-dark); + font-weight: 700; + font-size: 14px; +} + +.h2 { + margin: 0; + font-size: 19px; + font-weight: 600; + letter-spacing: -0.01em; +} + +.cardBody { + padding: 20px 24px 24px; +} + +.lead { + margin: 0 0 16px; + color: var(--xm-grey-text); +} + +.muted { + color: var(--xm-grey-text); + font-size: 14px; +} + +.strong { + font-weight: 600; +} + +.pill { + display: inline-flex; + align-items: center; + border-radius: 999px; + padding: 3px 10px; + font-size: 12px; + font-weight: 600; + white-space: nowrap; +} + +.ok { + background: var(--xm-tint); + color: var(--xm-green-dark); +} + +.todo { + background: #f3f4f6; + color: var(--xm-grey-text); +} + +.error { + background: var(--xm-red-bg); + color: var(--xm-red); +} + +p.error { + border-radius: 8px; + padding: 10px 12px; + font-size: 14px; +} + +.checks { + list-style: none; + margin: 0; + padding: 0; +} + +.checkRow { + display: grid; + grid-template-columns: 14px 190px 1fr; + align-items: baseline; + gap: 12px; + padding: 10px 0; + border-bottom: 1px solid #f0f1f3; +} + +.checkRow:last-child { + border-bottom: 0; +} + +.dot { + width: 10px; + height: 10px; + border-radius: 999px; + transform: translateY(1px); +} + +.dot.ok { + background: var(--xm-green); +} + +.dot.todo { + background: #d1d5db; +} + +.dot.error { + background: var(--xm-red); +} + +.checkName { + font-weight: 600; +} + +.callout { + margin: 18px 0 0; + padding: 16px 18px; + border-radius: 10px; + background: var(--xm-tint-soft); + border: 1px solid var(--xm-tint); +} + +.calloutTitle { + margin: 0 0 8px; + font-weight: 600; +} + +.ordered { + margin: 0 0 8px; + padding-left: 20px; +} + +.ordered li { + margin: 6px 0; +} + +.copyLine { + display: flex; + align-items: center; + gap: 10px; + margin: 8px 0; + padding: 6px 6px 6px 12px; + border: 1px solid var(--xm-grey-mid); + border-radius: 8px; + background: #fff; +} + +.copyLabel { + font-size: 12px; + font-weight: 600; + color: var(--xm-grey-text); + white-space: nowrap; +} + +.code { + flex: 1; + overflow-x: auto; + white-space: nowrap; + font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-size: 13px; +} + +.summary { + display: flex; + align-items: center; + gap: 16px; + justify-content: space-between; + padding: 14px 16px; + border: 1px solid var(--xm-grey-mid); + border-radius: 10px; + margin: 0 0 12px; +} + +.summary p { + margin: 0; +} + +.summaryTitle { + margin: 0 0 4px; + font-weight: 600; +} + +.next { + margin: 12px 0 0; +} + +.form { + display: grid; + gap: 14px; + margin: 8px 0 0; +} + +.grid2, +.grid3, +.grid4 { + display: grid; + gap: 14px; +} + +.grid2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.grid3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.grid4 { + grid-template-columns: 1fr 1.6fr 1fr 0.8fr; +} + +.label { + display: grid; + gap: 6px; + margin: 0; + font-size: 13px; + font-weight: 500; + color: var(--xm-dark); +} + +.input { + width: 100%; + font: inherit; + font-size: 15px; + color: var(--xm-dark); + background: #fff; + border: 1px solid var(--xm-grey-mid); + border-radius: 8px; + padding: 10px 12px; + outline: none; + transition: border-color 0.15s, box-shadow 0.15s; +} + +.input:focus { + border-color: var(--xm-green); + box-shadow: 0 0 0 3px rgba(0, 199, 104, 0.18); +} + +.actions { + display: flex; + gap: 10px; + justify-content: flex-end; + margin: 16px 0 0; +} + +.primaryButton, +.secondaryButton, +.ghostButton, +.dangerButton { + font: inherit; + font-weight: 600; + border-radius: 8px; + cursor: pointer; + transition: background 0.15s, border-color 0.15s, color 0.15s; +} + +.primaryButton { + background: var(--xm-green); + color: #fff; + border: 0; + padding: 11px 18px; + font-size: 15px; +} + +.primaryButton:hover { + background: var(--xm-green-dark); +} + +.primaryButton:disabled { + opacity: 0.6; + cursor: default; +} + +.secondaryButton { + background: transparent; + color: var(--xm-green-dark); + border: 1.5px solid var(--xm-green); + padding: 9.5px 16px; + font-size: 15px; +} + +.ghostButton, +.dangerButton { + background: transparent; + border: 1px solid var(--xm-grey-mid); + color: var(--xm-dark); + padding: 6px 12px; + font-size: 13px; +} + +.ghostButton:hover { + border-color: var(--xm-green); + color: var(--xm-green-dark); +} + +.dangerButton:hover { + border-color: var(--xm-red); + color: var(--xm-red); +} + +.primaryButton:focus-visible, +.secondaryButton:focus-visible, +.ghostButton:focus-visible, +.dangerButton:focus-visible { + outline: 3px solid rgba(0, 199, 104, 0.35); + outline-offset: 2px; +} + +.tableWrap { + overflow-x: auto; + margin: 0 0 4px; + border: 1px solid var(--xm-grey-mid); + border-radius: 10px; +} + +.table { + width: 100%; + border-collapse: collapse; + font-size: 14px; +} + +.table th { + text-align: left; + font-weight: 600; + color: var(--xm-green-dark); + background: var(--xm-tint); + padding: 10px 14px; +} + +.row td { + padding: 12px 14px; + border-top: 1px solid #e6e6e6; + vertical-align: top; +} + +.num { + font-variant-numeric: tabular-nums; + white-space: nowrap; +} + +.chips { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.chip { + font-size: 12px; + border-radius: 6px; + padding: 2px 8px; + background: #f3f4f6; + color: var(--xm-dark); + white-space: nowrap; +} + +.rowActions { + display: flex; + gap: 8px; + justify-content: flex-end; + align-items: center; + flex-wrap: wrap; +} + +.useRow { + padding: 0 14px 12px; + font-size: 14px; + color: var(--xm-grey-text); +} + +.cardForm { + margin: 12px 0 0; + padding: 18px; + border: 1px solid var(--xm-grey-mid); + border-radius: 10px; + background: var(--xm-tint-soft); +} + +.success { + margin: 12px 0 0; + padding: 18px; + border-radius: 10px; + background: var(--xm-tint-soft); + border: 1px solid var(--xm-tint); +} + +.success p { + margin: 0 0 8px; +} + +.footer { + margin: 24px 0 0; + text-align: center; + font-size: 13px; + color: var(--xm-grey-text); +} + +@media (max-width: 720px) { + .shell { + padding: 20px 16px 48px; + } + + .h1 { + font-size: 32px; + } + + .grid2, + .grid3, + .grid4 { + grid-template-columns: 1fr; + } + + .checkRow { + grid-template-columns: 14px 1fr; + } + + .checkRow .muted { + grid-column: 2; + } +} + +.link { + color: var(--xm-green-dark); + font-weight: 600; + text-decoration: underline; + text-underline-offset: 2px; +} + +.errorText { + color: var(--xm-red); +} diff --git a/app/crossmint/setup/setup.tsx b/app/crossmint/setup/setup.tsx new file mode 100644 index 0000000..b2c1160 --- /dev/null +++ b/app/crossmint/setup/setup.tsx @@ -0,0 +1,500 @@ +"use client"; + +import { CrossmintPaymentMethodManagement, CrossmintProvider, OrderIntentVerification } from "@crossmint/client-sdk-react-ui"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; +import { useRef, useState, useTransition, type FormEvent, type InputHTMLAttributes, type ReactNode } from "react"; +import { approveBudget, cancelBudget, refreshToken, saveBuyerProfile } from "./actions"; +import logo from "./crossmint-logo.svg"; +import styles from "./setup.module.css"; +import type { Budget, ProfileView } from "./view"; + +export interface Check { + state: "ok" | "todo" | "error"; + text: string; +} + +export interface SetupProps { + checks: { server: Check; operator: Check; token: Check }; + jwks?: { url: string; issuer: string; loopback: boolean }; + /** Only when Crossmint accepted Bell's token. The card form asks for a ten-minute token itself. */ + apiKey?: string; + profile?: ProfileView; + profileError?: string; + budgets: Budget[]; + defaults: { email?: string; countryCode?: string }; + configured: { profile: boolean; orderIntent: boolean }; +} + +// Crossmint's card form in Crossmint's colors, with the page's font stack. No web font is fetched. +const cardAppearance = { + variables: { + fontFamily: "Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", + borderRadius: "8px", + colors: { + accent: "#00C768", + textPrimary: "#0A1825", + textSecondary: "#6B7280", + borderPrimary: "#E5E7EB", + backgroundPrimary: "#FFFFFF", + danger: "#DC2626", + }, + }, +}; + +const language = () => (typeof navigator !== "undefined" && navigator.language) || "en-US"; +const field = (form: FormData, name: string) => String(form.get(name) ?? "").trim(); + +function Pill({ check }: { check: Check }) { + const label = check.state === "ok" ? "Ready" : check.state === "error" ? "Needs attention" : "To do"; + return {label}; +} + +function CopyLine({ value, label }: { value: string; label?: string }) { + const [copied, setCopied] = useState(false); + return ( +
+ {label ? {label} : null} + {value} + +
+ ); +} + +function Step({ number, title, aside, children }: { number: number; title: string; aside?: ReactNode; children: ReactNode }) { + return ( +
+
+ {number} +

{title}

+ + {aside} +
+
{children}
+
+ ); +} + +function CheckRow({ name, check }: { name: string; check: Check }) { + return ( +
  • + + {name} + {check.text} +
  • + ); +} + +function Connect({ checks, jwks }: Pick) { + const state: Check = Object.values(checks).every((check) => check.state === "ok") + ? { state: "ok", text: "" } + : Object.values(checks).some((check) => check.state === "error") ? { state: "error", text: "" } : { state: "todo", text: "" }; + return ( + }> +
      + + + +
    + {jwks && checks.token.state !== "ok" ? ( +
    +

    Let Crossmint verify Bell's token

    +
      +
    1. In the Crossmint console, open the project, then Integrate, API Keys, JWT authentication.
    2. +
    3. + Choose Custom tokens and set the JWKS endpoint. + + {jwks.loopback ? ( + + Crossmint cannot reach this address. Expose only this path over HTTPS, for example with a Cloudflare quick + tunnel, and paste the tunnel URL followed by /api/crossmint/jwks. A tunnel URL changes on every start, so + for a stable setup download the public key + file and host it at any HTTPS address you control. It holds only the public key. + + ) : null} +
    4. +
    5. + Set the issuer to the project id and the verifier id to sub. + +
    6. +
    7. Save, reload the console page to confirm Custom tokens stayed selected, then reload this page.
    8. +
    +

    A project has one sign-in method, so give Bell a Crossmint project of its own.

    +
    + ) : null} +
    + ); +} + +function DeliveryDetails({ profile, profileError, configured, countryCode }: { profile?: ProfileView; profileError?: string; configured: boolean; countryCode?: string }) { + const [saved, setSaved] = useState<{ id: string; profile: ProfileView }>(); + const [error, setError] = useState(""); + const [pending, start] = useTransition(); + const shown = saved?.profile ?? profile; + + function submit(event: FormEvent) { + event.preventDefault(); + const form = new FormData(event.currentTarget); + setError(""); + start(async () => { + const result = await saveBuyerProfile({ + first: field(form, "first"), + last: field(form, "last"), + email: field(form, "email"), + phone: field(form, "phone"), + street: field(form, "street"), + street2: field(form, "street2") || undefined, + postalCode: field(form, "postalCode"), + locality: field(form, "locality"), + region: field(form, "region") || undefined, + countryCode: field(form, "countryCode"), + }); + if (result.ok) setSaved({ id: result.id, profile: result.profile }); + else setError(result.message); + }); + } + + const pill: Check = shown ? { state: "ok", text: "" } : { state: "todo", text: "" }; + return ( + }> +

    + Checkouts fill these in instead of asking you in chat, so names and addresses stay out of the conversation. No + payment data is stored here. +

    + {profileError ?

    {profileError}

    : null} + {shown ? ( +
    +
    +

    {shown.name ?? "Saved delivery details"}

    +

    + {shown.place}, {shown.countryCode} + {shown.email ? ` · ${shown.email}` : ""} +

    +
    + {configured && !saved ? In use : null} +
    + ) : null} + {saved ? ( +
    +

    Add this line to .env.local and restart Bell:

    + +
    + ) : null} + {!shown ? ( +
    +
    + + + + +
    + + +
    + + + + +
    + {error ?

    {error}

    : null} +
    + +
    +
    + ) : null} +
    + ); +} + +function Input({ label, name, ...rest }: { label: string; name: string } & InputHTMLAttributes) { + return ( + + ); +} + +// The card network's verification window, in Crossmint's colors. +const verificationAppearance = { + variables: { borderRadius: "8px", colors: { accent: "#00C768", textPrimary: "#0A1825", textSecondary: "#6B7280", border: "#E5E7EB", success: "#00A846" } }, +}; + +function BudgetRow({ budget, apiKey, onCancel }: { budget: Budget; apiKey?: string; onCancel: (id: string) => void }) { + const router = useRouter(); + const [show, setShow] = useState(false); + const [verifying, setVerifying] = useState(false); + const [verifyError, setVerifyError] = useState(""); + const live = budget.live; + return ( + <> + + + {budget.merchantName ?? "Any merchant"} + {budget.merchantHost ? · {budget.merchantHost} : null} + + + {budget.available} + {budget.total ? ` of ${budget.total}` : ""} {budget.currency} + + {new Date(budget.expiresAt).toLocaleDateString()} + +
    + {budget.rails.map((rail) => {rail})} +
    + + + {budget.inUse ? In use : null} + {!live ? {budget.status} : null} + {live && budget.verify && apiKey ? ( + + ) : null} + {live && !budget.inUse ? : null} + {live ? : null} + + + {verifying && budget.verify && apiKey ? ( + + + Your card network asks you to confirm this budget, by code or passkey, before Bell can pay in its own browser. + + [0]["orderIntent"]} + displayName="Bell" + appearance={verificationAppearance} + onVerificationComplete={() => { setVerifying(false); router.refresh(); }} + onVerificationError={() => { setVerifying(false); setVerifyError("The card network did not confirm the budget. Try again."); }} + /> + + + + ) : null} + {verifyError ? ( + + {verifyError} + + ) : null} + {show ? ( + + + Add this line to .env.local and restart Bell: + + + + ) : null} + + ); +} + +type Draft = Parameters[0]; + +function CardAndBudget({ apiKey, budgets, defaults, ready }: { apiKey?: string; budgets: Budget[]; defaults: SetupProps["defaults"]; ready: boolean }) { + const router = useRouter(); + const [stage, setStage] = useState<"list" | "form" | "card" | "done">("list"); + const [draft, setDraft] = useState>(); + const [card, setCard] = useState<{ id: string; label: string }>(); + // One approval at a time; the draft's idempotency key covers retries that reach Crossmint. + const approving = useRef(false); + const [jwt, setJwt] = useState(); + const [result, setResult] = useState(); + const [error, setError] = useState(""); + const [pending, start] = useTransition(); + + function toCard(event: FormEvent) { + event.preventDefault(); + const form = new FormData(event.currentTarget); + setError(""); + setDraft({ + amount: field(form, "amount"), + currency: field(form, "currency"), + days: Number(field(form, "days")), + description: field(form, "description"), + merchant: { name: field(form, "merchantName"), url: field(form, "merchantUrl"), countryCode: field(form, "merchantCountry") }, + consumer: { email: field(form, "email"), countryCode: field(form, "consumerCountry"), languageCode: language() }, + idempotencyKey: crypto.randomUUID(), + }); + setCard(undefined); + start(async () => { + const token = await refreshToken(); + if (!token.ok) return setError(token.message); + setJwt(token.jwt); + setStage("card"); + }); + } + + function approve() { + if (!draft || !card || approving.current) return; + approving.current = true; + setError(""); + start(async () => { + try { + const outcome = await approveBudget({ ...draft, paymentMethodId: card.id }); + if (!outcome.ok) return setError(outcome.message); + setResult(outcome.budget); + setStage("done"); + router.refresh(); + } finally { + approving.current = false; + } + }); + } + + function cancel(id: string) { + if (!window.confirm("Cancel this budget? Nothing more can be spent from it.")) return; + start(async () => { + const outcome = await cancelBudget(id); + if (!outcome.ok) setError(outcome.message); + router.refresh(); + }); + } + + const pill: Check = budgets.some((budget) => budget.inUse && budget.live) + ? { state: "ok", text: "" } + : { state: ready ? "todo" : "error", text: "" }; + return ( + }> +

    + Approve how much Bell may spend, at which store, and until when. You still approve every payment in chat, and Bell + checks it against this budget before paying. +

    + {!ready ?

    Connect Bell to Crossmint first.

    : null} + {ready && budgets.length ? ( +
    + + + + + {budgets.map((budget) => )} +
    StoreLeftExpiresCard rails
    +
    + ) : null} + {error ?

    {error}

    : null} + + {ready && stage === "list" ? ( +
    + +
    + ) : null} + + {stage === "form" ? ( +
    +
    + + + +
    +
    + + + +
    + +
    + + +
    +
    + + +
    +
    + ) : null} + + {stage === "card" && apiKey && jwt && draft ? ( +
    + {!card ? ( + <> +

    + Pick a saved card or add one. Card details go straight to Crossmint's vault and never reach Bell. +

    + + { + if ("paymentMethodId" in method && method.type === "card") { + setError(""); + setCard({ id: method.paymentMethodId, label: `${method.card.brand} ending ${method.card.last4}` }); + } else setError("Choose a card. Bank accounts cannot back a budget."); + }} + /> + + + ) : ( +
    +
    +

    + Approve {draft.amount} {draft.currency.toUpperCase()} at {draft.merchant.name} for {String(draft.days)} days? +

    +

    On your {card.label}. You still approve every payment in chat.

    +
    + +
    + )} +
    + +
    +
    + ) : null} + + {stage === "done" && result ? ( +
    +

    + Budget approved: {result.available} {result.currency} + {result.merchantName ? ` at ${result.merchantName}` : ""} until {new Date(result.expiresAt).toLocaleDateString()} +

    +

    + {result.networkRail + ? "The card has a Visa or Mastercard agent rail, so Bell can also pay in its own browser." + : result.verify + ? "Crossmint checkouts can pay with it now. To let Bell also pay in its own browser, use Verify card in the list above." + : "Crossmint checkouts pay this card through Crossmint's encrypted card, so no network rail is needed."} +

    +

    Add this line to .env.local and restart Bell:

    + +
    + +
    +
    + ) : null} +
    + ); +} + +export default function Setup(props: SetupProps) { + const ready = props.checks.token.state === "ok" && Boolean(props.apiKey); + return ( +
    +
    +
    + Crossmint + + Bell + + Operator +
    +
    +

    Payments setup

    +

    + Let Bell buy at any store with your own card. Crossmint runs the checkout, and you approve every payment in chat. +

    +
    + + + +

    Restart Bell after changing .env.local. This page signs in to Crossmint for ten minutes; reload it to continue.

    +
    +
    + ); +} diff --git a/app/crossmint/setup/view.ts b/app/crossmint/setup/view.ts new file mode 100644 index 0000000..c030972 --- /dev/null +++ b/app/crossmint/setup/view.ts @@ -0,0 +1,63 @@ +import type { BuyerProfile } from "../../../server/crossmint/client"; +import { describeRail, type OrderIntentSummary } from "../../../server/crossmint/operator"; + +/** What the setup page shows about a budget (an order intent). */ +export interface Budget { + id: string; + status: string; + available: string; + total?: string; + currency: string; + merchantName?: string; + merchantHost?: string; + expiresAt: string; + rails: string[]; + /** A Visa or Mastercard agent rail is active, so Bell's own browser can pay with it too. */ + networkRail: boolean; + /** CROSSMINT_ORDER_INTENT_ID names this budget. */ + inUse: boolean; + /** Active and not yet expired when the page was rendered. */ + live: boolean; + /** + * With paying in Bell's browser switched on, the order intent Crossmint's verification component + * needs when a Visa or Mastercard rail is still pending verification. + */ + verify?: OrderIntentSummary; +} + +export function budgetView(intent: OrderIntentSummary, configuredId?: string, now = Date.now(), cards = false): Budget { + const pending = intent.rails.some((rail) => rail.rail === "agentic-token" && rail.status === "pending_verification"); + const host = intent.merchant?.url ? URL.parse(intent.merchant.url)?.hostname : undefined; + return { + id: intent.orderIntentId, + status: intent.status, + available: intent.amount.available, + ...(intent.amount.total ? { total: intent.amount.total } : {}), + currency: intent.amount.currency.toUpperCase(), + ...(intent.merchant?.name ? { merchantName: intent.merchant.name } : {}), + ...(host ? { merchantHost: host } : {}), + expiresAt: intent.expiresAt, + rails: intent.rails.map(describeRail), + networkRail: intent.rails.some((rail) => rail.rail === "agentic-token" && rail.status === "active"), + inUse: Boolean(configuredId) && intent.orderIntentId === configuredId, + live: intent.status === "active" && Date.parse(intent.expiresAt) > now, + ...(cards && pending && intent.verificationConfig ? { verify: intent } : {}), + }; +} + +/** What the setup page shows about the saved delivery details. */ +export interface ProfileView { + name?: string; + place: string; + email?: string; + countryCode: string; +} + +export function profileView(profile: BuyerProfile): ProfileView { + return { + ...(profile.name ? { name: `${profile.name.first} ${profile.name.last}` } : {}), + place: [profile.shipping.postalCode, profile.shipping.locality].filter(Boolean).join(" "), + ...(profile.contact?.email ? { email: profile.contact.email } : {}), + countryCode: profile.shipping.countryCode, + }; +} diff --git a/docs/crossmint.md b/docs/crossmint.md new file mode 100644 index 0000000..53a8300 --- /dev/null +++ b/docs/crossmint.md @@ -0,0 +1,410 @@ +# Crossmint Agent Checkouts + +Bell's `crossmint_checkout` and `crossmint_pay` tools buy through +[Crossmint Agent Checkouts](https://docs.crossmint.com/agents/checkouts/overview), part of the +Agent Commerce Toolkit. It works at any store. One call carries a product URL, a sentence, and a +spending cap. Crossmint picks the fastest path for that store, the merchant API, an agent protocol, +or its own checkout browser, and returns a run with status snapshots. The person pays with their own +card, at stores worldwide. The card number never reaches Bell or the model. + +```text +Bell -> create run (URL, task, cap) -> Crossmint works through the store's checkout + -> running (progress) -> Bell tells the person what Crossmint is doing + -> awaiting_input (form) -> Bell answers from the conversation + -> awaiting_input (payment) -> Eve asks the person to approve the exact total + -> server checks total, currency, merchant, cap -> pays + -> succeeded (receipt) -> Bell reports the order +``` + +The checkout runs in Crossmint's service, not in this conversation's browser, so it needs no +Browserbase plan and works the same with Bell's local browser. Nothing in the Link integration, the +browser runtime, or the hooks changes. With the Crossmint variables unset, both tools answer +`not_configured`. To keep the checkout in this conversation's browser and pay with a one-time card +instead, see [Agent Cards in Bell's browser](#agent-cards-in-bells-browser). + +## Configure + +Set these server-only values in Bell's ignored `.env.local`: + +```dotenv +CROSSMINT_SERVER_API_KEY= +CROSSMINT_USER_ID= +# Optional. Ceiling for any single checkout's cap, "amount currency". +CROSSMINT_MAX_COST=50.00 EUR +# Optional. Exact HTTPS origins a checkout may start from. Empty allows any store. +CROSSMINT_ALLOWED_MERCHANTS=https://shop.example +# Written by the setup page below. +CROSSMINT_BUYER_PROFILE_ID= +CROSSMINT_ORDER_INTENT_ID= +``` + +Create the key in the [Crossmint console](https://www.crossmint.com/console) with the +`agent-checkouts.create`, `agent-checkouts.read`, `agent-checkouts.update`, and +`agent-checkouts.cancel` scopes, plus `agent-checkouts.buyer-profiles.create` and +`agent-checkouts.buyer-profiles.read` for the setup page. Agent Checkouts runs in production only, +so a staging key answers `unauthorized`. A client key (`ck_`) is rejected at startup. + +`CROSSMINT_USER_ID` identifies the buyer to Crossmint. Bell serves one trusted operator, so a fixed +value is enough. Every run, buyer profile, order intent, and receipt is scoped to it. + +`CROSSMINT_MAX_COST` and `CROSSMINT_ALLOWED_MERCHANTS` are checked before a run exists, so a refused +request is never billed. They bound what a prompt can ask for. The order intent bounds what can be +paid. + +Restart Bell after changing these values. No database or migration is involved. + +## Set up payments in Bell + +Two things make checkouts pay without questions: saved delivery details (a buyer profile) and an +approved budget on the person's card (an order intent). Bell's operator page at +`/crossmint/setup` sets up both. It asks for `BELL_OPERATOR_USERNAME` and `BELL_OPERATOR_PASSWORD`, +also when Bell runs locally. + +Approving a budget is a call Crossmint accepts only for a signed-in user: a client key together with +that user's JWT, never a server key. Bell serves one operator, so it signs that JWT itself: RS256, +issuer the project id, subject `CROSSMINT_USER_ID`, audience `crossmint.com`, valid ten minutes. +Crossmint checks it against the public key Bell serves at `/api/crossmint/jwks`. Add to `.env.local`: + +```dotenv +# Client key (ck_) with the payment-methods.* and order-intents.* scopes. BELL_PUBLIC_URL must be an allowed origin. +CROSSMINT_CLIENT_API_KEY= +# The Crossmint project id. Bell's operator token carries it as the issuer. +CROSSMINT_PROJECT_ID= +# Base64-encoded PEM RSA private key, 2048 bits or more, that signs the operator token. +CROSSMINT_JWT_PRIVATE_KEY= +``` + +Generate the private key once and keep it stable across restarts: + +```sh +openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 | base64 | tr -d '\n' +``` + +Then open `/crossmint/setup`. It checks each step live and says what is missing: + +1. **Connect Bell to Crossmint.** The page lists Crossmint's budgets with Bell's token, which proves + the whole chain. If Crossmint rejects the token, the page shows the two values to paste in the + console under Integrate, API Keys, JWT authentication: choose Custom tokens, set the JWKS endpoint + and the issuer, keep the verifier id `sub`, save, and reload the console page to confirm Custom + tokens stayed selected. Crossmint fetches the JWKS endpoint over HTTPS. A deployed Bell serves it + at `/api/crossmint/jwks`. A Bell on your laptop needs that one path exposed, for + example through a Cloudflare quick tunnel, whose URL changes on every start. For a stable setup, + download the public key file from the page and host it at any HTTPS address you control; it holds + only the public key. A project has one sign-in method, so give Bell a Crossmint project of its own. +2. **Delivery details.** Save the name, email, phone, and shipping address checkouts use instead of + asking in chat. No payment data is stored. The page shows the `CROSSMINT_BUYER_PROFILE_ID` line + to add. +3. **Card and budget.** Enter the amount, currency, how many days it lasts, and the store's name, + HTTPS URL, and country. Then pick a saved card or add one in Crossmint's card form, whose fields + go straight to Crossmint's vault, and confirm the budget on that card. Bell registers the card for + order intents with your email, country, and language, which Crossmint requires and its card + component does not send, and then approves the budget once: each draft carries its own + idempotency key. The page lists every budget with what is left, its expiry, and its card + rails, marks the one `CROSSMINT_ORDER_INTENT_ID` names, and cancels budgets you no longer need. + +Agent Checkouts pays with any card Crossmint can save. A card without a Visa Intelligent Commerce or +Mastercard Agent Pay rail, such as a Visa issued outside the United States, is paid through +Crossmint's encrypted card inside its vault, so the budget's rail list can show no active card rail +and the checkout still pays. + +Add both lines the page shows to `.env.local` and restart Bell. + +## Try it in five minutes + +This run needs only `CROSSMINT_SERVER_API_KEY` and `CROSSMINT_USER_ID`. Without a budget it reaches +the payment step and stops there, so nothing is bought. Pick a product under a few dollars at a store +that ships to you. + +1. Start Bell with `pnpm dev` and open `http://127.0.0.1:4320`. Local development auth signs the web + conversation in, which the payment step requires. +2. Send "Buy one of https://shop.example/products/sticker-pack with standard delivery, max 20 USD". + Bell starts the run and, within seconds, says what Crossmint is doing. It posts a short line at + each new stage, such as finding the product or filling in the delivery details. +3. Answer the questions Bell relays, such as a size or an email. With delivery details saved, most of + them do not come up. +4. At the payment step Bell calls `crossmint_pay`. Eve pauses and shows "Pay 12.49 USD at Example + Shop (shop.example) with your saved card?". Approve it. The server fetches the live request, + checks it, finds no budget, and answers `payment_not_configured`. +5. Say "Cancel it". Bell cancels the run and the status becomes `cancelled`. + +Crossmint bills each run that starts, including runs that end `blocked`. The first thousand runs a +month are free. The run appears in the Crossmint console under Agent Checkouts with the same id Bell +reports. To buy for real, approve a budget on the setup page, set `CROSSMINT_ORDER_INTENT_ID`, and +repeat the steps. The approval is the same. The server then pays, and `succeeded` with +`purchase.kind` `receipt_captured` carries `receipt.total` and `receipt.merchantOrderId`. + +## Use + +With `pnpm dev` running, in a web conversation or a Linq chat, give Bell the product URL, what to +buy, and the cap. Bell starts the run with `crossmint_checkout` and follows `requiredAction`. + +While the run works, `start` returns within about twenty-five seconds and each `status` call returns +at the next new stage, at least fifteen seconds and at most a minute later. Bell tells you each new +stage in one short sentence and calls `status` again, so the conversation never sits on "Working" +for minutes. + +When Crossmint asks a form question, Bell answers from what you said or asks you, then calls +`answer` with one value per field key. A choice field lists its option values. Fields marked +`protected`, such as one-time codes, passwords, and card data, cannot be answered through the model. +Bell declines or asks you to finish in Crossmint's hosted flow. + +At the payment step Bell calls `crossmint_pay` with the amount, currency, merchant, and merchant name +copied from the request. Eve pauses and asks you to approve. Approving runs the tool and cancelling +does not. Only the authenticated sender who asked for the purchase can approve. A payment request for +a method other than a card, such as Klarna, is refused, because an order intent cannot pay it. + +`succeeded` with `purchase.kind` `receipt_captured` is the only result Bell reports as a placed order. +`confirmed_without_receipt` and `nothing_placed` are reported as what they are. `blocked` carries a +code such as `merchant.payment_declined`, `policy.max_cost_exceeded`, or `product.item_unavailable`. +`failed` carries a reason such as `cost_limit` or `input_expired`. Bell reports these and does not +retry on its own. `cancel` stops a run that is still in progress. Keep the cap tight and do not start +a second run for the same request while one is unresolved. + +## How payment is guarded + +Approval in chat is not the control. Eve's tool approval is. `crossmint_pay` is declared with +`approval: always()`, so the runtime stops before executing it and shows the person the amount, +currency, and payee the model put in the call, in plain words such as "Pay 16.90 EUR at Zara +(payments.zara.com) with your saved card?". After approval the server fetches the live payment +request from Crossmint and compares it with the amount, currency, merchant, and store name and with +the cap the run started with. Any difference, an expired or replaced request, a method other than a card, a +`maximum` instead of an `exact` amount, or a run this conversation did not start refuses the payment +and answers the reason. The approval dialog shows the model's numbers. The cross-check makes sure +they are Crossmint's numbers. + +Payments need an authenticated sender, which is a verified Linq number, the HTTP Basic operator, or +local development auth. The anonymous web demo can start and inspect runs but cannot pay, and the +approval response policy rejects anyone other than the principal who requested the call. + +The setup page is for the operator only. A root proxy asks for the HTTP Basic credentials, refuses +cross-origin writes, and forbids other sites to frame the page. The page and every action check the +credentials and the origin again before signing a token or calling Crossmint. The browser receives +only the client key, and a ten-minute operator token when it opens Crossmint's card form. + +## Transcript boundary + +Only a projection of each snapshot reaches the model. That is the run id, status, revision, the open +question with its form fields or payment amount and merchant, the result summary with receipt +metadata, and, while the run works, its progress as a fixed stage phrase chosen from Crossmint's +activity kinds. Crossmint's own progress text is never passed on: it can name the buyer while the +delivery details are applied, and it is written while reading merchant pages. Browser +embed URLs, payment authorization links, the echoed input, provider error bodies, and any unexpected +field are dropped before Eve can persist them. The API key, buyer id, buyer profile, and order intent +id are read from the server environment inside the tools and never appear in tool arguments or +output. Nothing the setup page reads or saves reaches the model. + +Runs are registered per conversation in process memory. After a restart or worker change an +unfinished run cannot be resumed from chat. Reconcile it in the Crossmint console before starting +another. + +Crossmint's and the store's own records are outside Bell's control. Transcripts still contain the +store, items, totals, and form answers, so apply your host's retention policy. + +## Verify + +`pnpm check` runs mock provider tests. They pin request bodies and headers to the documented API, +prove no provider body leaks, exercise the merchant allowlist and the ceiling, project form fields +with their option values and protected handling, run the payment cross-check through every refusal +reason, including a store name that is not Crossmint's, cover polling with an answered request +skipped, the timeout and cancellation paths, progress stages without Crossmint's free text, the +minimum wait between updates and a cancellation during a progress read, per-conversation run +isolation, the approval wording, buyer profiles, and both tools up to `payment_not_configured`. The +setup tests cover the operator-only proxy with its framing headers, the page and actions refusing +missing credentials and other origins, the token the card form receives, the state when Crossmint +rejects the token, a missing setting, and a budget approval that registers the card with an email +and sends one idempotency key before creating the order intent. No test calls Crossmint. + +For a live smoke test without Bell, start one run from the command line: + +```sh +node scripts/demo-crossmint.mjs https://shop.example/products/sticker-pack 20.00 USD +``` + +The command loads `.env`, then `.env.local` when present. It starts the checkout with the key, buyer +id, and buyer profile, prints the run id, each status change and each new progress stage, and stops at +the first question or the first terminal state. It answers nothing, so nothing is bought, and it +prints no secrets. Cancel the run in the Crossmint console afterwards. Crossmint bills the run. + +For the full flow, follow [Try it in five minutes](#try-it-in-five-minutes). Watch the run in the +Crossmint console and compare the receipt with the store's confirmation before trusting the flow for +anything larger. + +References: [Agent Checkouts overview](https://docs.crossmint.com/agents/checkouts/overview), +[quickstart](https://docs.crossmint.com/agents/agent-checkouts-quickstart), +[follow a checkout](https://docs.crossmint.com/agents/checkouts/follow-run), +[pay for a checkout](https://docs.crossmint.com/agents/checkouts/payments), +[buyer profiles](https://docs.crossmint.com/agents/checkouts/configure), +[register a card](https://docs.crossmint.com/agents/payment-methods/cards/register-card), +[custom JWT authentication](https://docs.crossmint.com/introduction/platform/api-keys/custom-jwt-auth-guide), +[statuses and codes](https://docs.crossmint.com/agents/checkouts/statuses), +[API reference](https://docs.crossmint.com/api-reference/agent-checkouts). + +## Agent Cards in Bell's browser + +`crossmint_card_checkout` keeps the checkout in this conversation's browser and pays with a +[Crossmint agent card](https://docs.crossmint.com/agents/cards/overview). Bell drives the merchant +page with its usual tools and maps the card inputs with exact CSS selectors. The tool mints a +one-time card from the budget the person approved on the setup page and fills it on the server. The +card is the person's own, enrolled in Visa Intelligent Commerce or Mastercard Agent Pay, so rewards, +refunds, and chargeback rights work as for any purchase on it. + +```text +Bell -> merchant checkout in Bell's browser -> card inputs mapped by CSS selector + -> crossmint_card_checkout -> Eve asks the person to approve the exact total + -> server reads the order intent -> status, merchant, currency, balance, expiry, rail + -> one-time card, minted once -> filled, pay pressed once, browser goes private +``` + +Mastercard credit and debit cards from any country work through Mastercard Agent Pay. U.S.-issued +Visa credit and debit cards work through Visa Intelligent Commerce, except business, prepaid, Chase, +and Fidelity cards. Any other card is refused with `no_card_rail`; Agent Checkouts above takes it. + +### Configure + +Agent Cards uses the Agent Checkouts settings and the setup keys above, and is off until you turn it +on: until then `crossmint_card_checkout` answers `not_configured`, and the database requirement below +does not apply. The setup keys alone only approve budgets for Agent Checkouts. The browser lock that +makes card entry safe needs `LINK_SANDBOX=0` and `DATABASE_URL`; without the lock, Bell refuses before +any card is issued. + +```dotenv +# Turn on paying in Bell's own browser with a one-time card. +CROSSMINT_CARD_CHECKOUT=1 +# Optional. Exact payment-frame origins per merchant origin, as a JSON object. +CROSSMINT_CHECKOUT_ORIGINS={} +DATABASE_URL= +``` + +The card path needs PostgreSQL. With `DATABASE_URL` exported, apply the browser privacy table: + +```sh +psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f migrations/003_link_checkout.sql +``` + +Once card numbers have been typed into a browser, Bell records that conversation's browser there +and refuses every later browser tool on it. With Agent Cards on, every browser tool needs the +database. + +`CROSSMINT_CHECKOUT_ORIGINS` maps a merchant origin to the origins of its payment frames, such as a +payment provider's card iframe, for example `{"https://shop.example":["https://pay.example"]}`. Bell +fills inputs only on the merchant origin and on those frames. + +### Set up the card + +Approve a budget on `/crossmint/setup` as described in +[Set up payments in Bell](#set-up-payments-in-bell). For this path the budget must name the merchant, +and its Visa Intelligent Commerce or Mastercard Agent Pay rail must be verified. With +`CROSSMINT_CARD_CHECKOUT=1`, a budget whose rail is still pending shows a Verify card button: Visa +sends a one-time code and asks for a passkey, and Mastercard opens a hosted page. The page reloads +once the network confirms, and the rail reads `active`. + +See [saving a card](https://docs.crossmint.com/agents/payment-methods/cards/save-card), +[registering it](https://docs.crossmint.com/agents/payment-methods/cards/register-card), and +[creating an order intent](https://docs.crossmint.com/agents/payment-methods/cards/create-agent-card). + +### Use + +At the merchant's payment step Bell calls `crossmint_card_checkout` with the total, the currency, +the checkout page's URL or host, and exact CSS selectors for the card number, the CVC, and the +expiry, either as `expiry` (MM/YY) or as `exp_month` (MM) and `exp_year` (YYYY), plus the pay +button. A target inside an iframe adds a `frame` selector. Billing address inputs are not accepted. +Bell fills those with its usual tools before the call, because the one-time card carries no +address. + +Eve pauses and shows "Pay 12.49 EUR at shop.example with your Crossmint agent card?". Approving +runs the tool once. Only the authenticated sender who asked can approve. + +The tool answers `submission_attempted`, `merchant_confirmation_observed`, or `outcome_unknown`. +None of them proves payment. The browser is private after the card is entered, so the person checks +the order through human handoff. Bell does not retry an uncertain purchase. A refusal answers +`error` with a reason, such as `merchant_mismatch`, `insufficient_allowance`, +`rail_pending_verification`, or `cvc_recollection_required`, and says what the person has to do. + +### How payment is guarded + +`crossmint_card_checkout` is declared with `approval: always()`, so the runtime stops before +executing it and shows the person the amount, currency, and merchant the model put in the call. +After approval, and before anything is minted, the server checks: + +- `CROSSMINT_ALLOWED_MERCHANTS` and `CROSSMINT_MAX_COST` from the Agent Checkouts settings. +- The order intent is active and expires more than a minute from now. +- It names this merchant, by host. +- Its currency is this payment's currency, and what is left on it covers the amount. +- Its Visa Intelligent Commerce or Mastercard Agent Pay rail is active for card numbers. +- On the merchant page, every mapped input and the pay button match exactly once, on the merchant + origin or a configured payment frame. + +Any difference refuses the payment with its own reason. Only then does the server mint. A mint +spends its amount at once, even if the card is never used. It carries an idempotency key derived +from the conversation and the tool call, so a repeat of the same call never issues a second card. +Crossmint answers `credential_already_issued` instead. The card network enforces the amount and the +merchant on the one-time card as well. + +The card is read inside the fill and never returned. Bell types it into the mapped inputs, presses +pay once, clears the inputs it can still reach, and marks the browser private. Merchant scripts may +keep their own copy of what was typed. + +The `network-token` format and the `encrypted-card` rail are out of scope here: a network token +needs a payment processor integration, and the encrypted card returns the real card number. Agent +Checkouts pays encrypted cards inside Crossmint's vault instead. + +### Transcript boundary + +The model sees its own tool input, which is the total, currency, merchant, and selectors, the fill +status, and refusal reasons. The order intent id, the operator token, the client key, Crossmint's +error messages, and the card are read on the server and never appear in tool arguments or output. + +### Verify + +`pnpm check` runs mock tests for the card path. They pin the order intent read, the mint request, +its headers, and its idempotency key to the documented API. They refuse with each pre-mint reason, +map Crossmint's error codes including the two 409 responses an operator must act on, project the +card into Bell's field mapping, prove the tool stays off without `CROSSMINT_CARD_CHECKOUT=1`, refuse +before any mint when the browser lock is not held, answer "do not retry" for any failure after a +mint, and check that no card value or Crossmint message reaches tool output. The setup tests prove the Verify +card step appears only with the card path on. + +The staging smoke below needs a staging project with Bell's JWKS reachable over HTTPS, +`CROSSMINT_API_BASE_URL` set to `https://staging.crossmint.com/api/unstable`, and a `ck_staging_` +client key. + +1. Save the [test card](https://docs.crossmint.com/agents/payment-methods/cards/test-agent-cards) + `4242 4242 4242 4242` on the setup page, approve a 10.00 USD budget for + `https://merchant.invalid`, and verify its Visa rail. +2. Export a token with `export TOKEN=$(pnpm -s crossmint:operator-jwt)` and the values from + `.env.local`, then read the order intent. Expect the `agentic-token` rail `active` and + `available` `10.00`: + + ```sh + curl -s https://staging.crossmint.com/api/unstable/order-intents/$CROSSMINT_ORDER_INTENT_ID \ + -H "X-API-KEY: $CROSSMINT_CLIENT_API_KEY" -H "Authorization: Bearer $TOKEN" -H "Origin: $BELL_PUBLIC_URL" \ + | jq '{status, amount, rails}' + ``` + +3. Mint 1.00 with an idempotency key, printing only metadata. Expect `agentic-token` and `1.00 USD`: + + ```sh + curl -s -X POST https://staging.crossmint.com/api/unstable/order-intents/$CROSSMINT_ORDER_INTENT_ID/credentials \ + -H "X-API-KEY: $CROSSMINT_CLIENT_API_KEY" -H "Authorization: Bearer $TOKEN" -H "Origin: $BELL_PUBLIC_URL" \ + -H "Content-Type: application/json" -H "Idempotency-Key: bell-smoke-1" \ + -d '{"rail":"agentic-token","provider":"vic","amount":{"value":"1.00","currency":"USD"},"credential":{"format":"card"}}' \ + | jq '{rail, provider, amount, expiresAt}' + ``` + +4. Repeat step 3 unchanged. Expect HTTP 409 with `ORDER_INTENT_CREDENTIAL_ALREADY_ISSUED`. Read the + order intent again and expect `available` `9.00`, spent once. +5. Run the opt-in browser fill on the synthetic checkout page, which types a card of the same shape + into a local Chrome and checks the safe status, the cleared inputs, and the quarantine: + + ```sh + TEST_LINK_BROWSER=1 pnpm vitest run tests/link-checkout-browser.test.ts + ``` + +Never run the smoke against a real merchant or with a production key. + +References: [Agent Cards overview](https://docs.crossmint.com/agents/cards/overview), +[rails and PCI](https://docs.crossmint.com/agents/cards/rails-and-pci), +[Agent Cards quickstart](https://docs.crossmint.com/agents/cards-quickstart), +[get order intent](https://docs.crossmint.com/api-reference/agentic-commerce/order-intents/get-order-intent), +[create credentials](https://docs.crossmint.com/api-reference/agentic-commerce/order-intents/get-order-intent-credentials), +[verify the selected rail](https://docs.crossmint.com/agents/payment-methods/cards/create-agent-card). diff --git a/docs/repository.md b/docs/repository.md index f77d120..1700c3e 100644 --- a/docs/repository.md +++ b/docs/repository.md @@ -33,6 +33,7 @@ lifecycle; channel callbacks also handle terminal-session cleanup. Restart Bell | Link by Stripe | [Eve extension and tools](../agent/extensions/link/), [authorization](../agent/lib/link-auth.ts), [server implementation](../server/link/) | [Sandbox and wallet setup](link.md) | | 1Password | [Operator SDK/CLI access](../server/browser/vault/onepassword.ts), [personal authorization](../agent/lib/onepassword-auth.ts), [personal server implementation](../server/onepassword/) | [Operator credentials](browser-runtime.md#credentials-and-otp), [personal access status](onepassword.md) | | Baselayer | [Agent tool](../agent/tools/merchant_access.ts), [credential minting](../server/baselayer.ts), [merchant verification](../server/verified-merchant.ts) | [Merchant access](baselayer.md) | +| Crossmint | [Checkout tool](../agent/tools/crossmint_checkout.ts), [approved payment tool](../agent/tools/crossmint_pay.ts), [agent card tool](../agent/tools/crossmint_card_checkout.ts), [shared tool helpers](../agent/lib/crossmint.ts), [server client](../server/crossmint/client.ts), [payment cross-check](../server/crossmint/payment.ts), [operator calls](../server/crossmint/operator.ts), [operator token](../server/crossmint/operator-jwt.ts), [setup page](../app/crossmint/setup/page.tsx), [agent cards](../server/crossmint/cards.ts) | [Agent checkouts and agent cards](crossmint.md) | Personal 1Password Agentic Autofill is implemented but disabled by default pending hosted extension support and live verification. Keep `ONEPASSWORD_ENABLED=false` and the extension ID unset as diff --git a/package.json b/package.json index 9d283d3..cbd3a88 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "lint": "eslint . --max-warnings=0", "check": "pnpm test && pnpm typecheck && pnpm lint && pnpm build", "baselayer:mint": "node --env-file-if-exists=.env --env-file-if-exists=.env.local scripts/mint-baselayer-credential.mjs", + "crossmint:operator-jwt": "node --env-file-if-exists=.env --env-file-if-exists=.env.local scripts/crossmint-operator-jwt.mjs", "test:retirement:live": "node --env-file-if-exists=.env --env-file-if-exists=.env.local scripts/test-session-retirement.mjs" }, "dependencies": { @@ -25,6 +26,7 @@ "@ai-sdk/openai": "4.0.46", "@browserbasehq/sdk": "2.18.0", "@browserbasehq/stagehand": "4.3.0", + "@crossmint/client-sdk-react-ui": "4.12.1", "@stripe/link-integrations-eve": "0.3.4", "ai": "7.0.137", "eve": "0.79.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e71bd2c..8323077 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,9 @@ importers: '@browserbasehq/stagehand': specifier: 4.3.0 version: 4.3.0 + '@crossmint/client-sdk-react-ui': + specifier: 4.12.1 + version: 4.12.1(@dynamic-labs-wallet/primitives@1.1.33)(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) '@stripe/link-integrations-eve': specifier: 0.3.4 version: 0.3.4(eve@0.79.1(@opentelemetry/api@1.9.1)(ai@7.0.137(zod@4.6.7))(microsandbox@0.5.10)) @@ -80,12 +83,32 @@ importers: packages: + '@0no-co/graphql.web@1.3.4': + resolution: {integrity: sha512-imSwulOeDQodRy/olQmVEo2PiY6ntjkZ9eiGdw6lMYylh/tay9b7MusyJBmEnkL8GiKRKr6ltr+D42mY5bd8Bg==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + peerDependenciesMeta: + graphql: + optional: true + + '@0no-co/graphqlsp@1.18.0': + resolution: {integrity: sha512-A6ZId4J6l4KxN5ZtTFZaPtZcU0ikx9mB3kTzEVP3ui5c8srtPA1cGXqjhHFBsKt1ZP839RIHy//LrZMmbE4VAw==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 || ^6.0.0 + '@1password/sdk-core@0.5.0': resolution: {integrity: sha512-9g7LWOKRKdePZ85evVgE9xEom3DAg3hRIyQdOwLPvpL/F7KpDXmUHMi72rsqJxKaDbWApXmrYjDExMSPqUg7xw==} '@1password/sdk@0.5.0': resolution: {integrity: sha512-k6kov3pcA7PRg2tev9CgTfEf/3JSyAp11BPQNCEsqAD32QbqM032OXC1rfjyC8Ba0sfH+NHYZxcifUZToyGyYA==} + '@ably/msgpack-js@0.4.1': + resolution: {integrity: sha512-Sjxj6SOr17hExAVrsycN7u6oV4PhZcK7Z2S8dM71CH/butgO47cSo/TL6FJPCXUyDAzKkOWjMUpJGyZkEpyu4Q==} + + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@ai-sdk/gateway@4.0.110': resolution: {integrity: sha512-5IwnOR6v7KC+D9eddUqsCobXl/FbLUVb2LaQc/uyuQdpP3/n9s0YLc9zl4/W3IS/R2pjHrqUfCzEAeOu7bFLoQ==} engines: {node: '>=22'} @@ -173,6 +196,10 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/runtime@7.29.10': + resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==} + engines: {node: '>=6.9.0'} + '@babel/template@7.29.7': resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} @@ -185,6 +212,13 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} + '@base-org/account@1.1.1': + resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==} + + '@basis-theory/web-agentic@1.2.2': + resolution: {integrity: sha512-YipoQlOxPoU1gAUNr6ULs9Fngm9LGekNnD80yOyarfTVB55oIEYF/zCvdscNz0zCK43R0sIeGV9tarum8uiP7g==} + engines: {node: '>=18'} + '@browserbasehq/sdk@2.18.0': resolution: {integrity: sha512-uX1kiOB3lBWvt0sdIszGZkroLj+xvo7d6CC8ORn1mqPLq76Y4fJFDGdbdLWggDF3LxtnmwJCRVgSrLo3V9RctQ==} @@ -192,6 +226,258 @@ packages: resolution: {integrity: sha512-LDiAvJKkpcm2I/NP1B94DC/0hnjJ0NL7kjSKDeyXXyehISKuNRjwOpA2r3PXwmxmMz/o6DMFF4TJcYlsrMWXoA==} engines: {node: '>=22.18.0'} + '@coinbase/wallet-sdk@4.3.7': + resolution: {integrity: sha512-z6e5XDw6EF06RqkeyEa+qD0dZ2ZbLci99vx3zwDY//XO8X7166tqKJrR2XlQnzVmtcUuJtCd5fCvr9Cu6zzX7w==} + + '@crossmint/client-sdk-auth@1.3.31': + resolution: {integrity: sha512-Z1vl+brIW8hvYMvZK13nNYq8iYezX6BqOZdgaziww7D2dLl+qteoEgD6U8mTOalOidjG8acfFT59qVj607aXfw==} + + '@crossmint/client-sdk-base@4.6.1': + resolution: {integrity: sha512-5LtY0ilZXnVxPJxP/1Nq4/SpuF3SlhhVpoxEpuXM2rwvVOowGcn+Wf2dVeOjqmyUPayX6ZRLrF86W8202FOwgg==} + + '@crossmint/client-sdk-react-base@2.4.6': + resolution: {integrity: sha512-j0R/G9e6LXotDt2yNCPWWw6mv1m6zw2iLM4ODC4fXvnrTSY9Wje+5ghSE2LGl7Iz/akj2G/sjHTQHOv5s8UTZg==} + peerDependencies: + react: '>=17.0.2' + + '@crossmint/client-sdk-react-ui@4.12.1': + resolution: {integrity: sha512-7WxlhCTjejycerTtQbuvYP4ngiJPgp5HEj3kt8vDFa+21E5epDGQm6qmdZlALP0rgScC5OiTMtbpYs7v818ZXQ==} + peerDependencies: + '@solana/web3.js': ^1.98.1 + react: '>=17.0.2' + react-dom: '>=17.0.2' + + '@crossmint/client-sdk-window@1.2.0': + resolution: {integrity: sha512-cKBvTjs/mPt/HthK/5hIhGpjIDM/kl1T/1Xb7QjI4rrC/1O0fUEXASz3vCxPB1R8Dxm/5gFM3EX0qAS+g9gQIw==} + + '@crossmint/client-signers-cryptography@0.0.5': + resolution: {integrity: sha512-wS2MLFthBrOOkpwh344iSTTLXOVmLE3vy/rB7oBe9fqDFIQ1QLh2+QWw/D/n4OfVMo8kmImK3XnO+XM1xtAPKg==} + + '@crossmint/client-signers@0.3.1': + resolution: {integrity: sha512-86gCuNQlJ2baNMyISUBWmU6vmnQ/5f0wetBq8td0W5Rr/KG5T37PD69vtejX0CDOgfZm3eX519Dv+Hc6bJflUg==} + + '@crossmint/common-sdk-auth@1.1.29': + resolution: {integrity: sha512-4AnPaWDnxmPV8vsj6B9hwMDBiBgRGoM3gv1S0lzm2rDO7Uod9nqzolk8FNtLNYXUZzADxdlsbkCuG/fNbwEADg==} + + '@crossmint/common-sdk-base@0.13.0': + resolution: {integrity: sha512-ReY//P8DZszmVBDXs4saV/1U4f414l7wDpGUAMGRNWllZceQ8s3t+WCT/hghz46eg/ZzS1VVcwdFbugLgk9hew==} + + '@crossmint/wallets-sdk@1.20.6': + resolution: {integrity: sha512-R2KvFAaK4DXSv++vwnv3LkETdzH9CN2kFwdsGi885ItkXC22UVf+P/1NCsblt00DJhFEMgm8CjajrNBwPA9z1w==} + peerDependencies: + '@solana/web3.js': ^1.98.1 + + '@datadog/browser-core@6.24.1': + resolution: {integrity: sha512-ViLqvvCrZtKRCrSCcrZmSbc4Th7Y0rUQ7PruP1KGNgmE2fY4rrRP/n77zXuF8y/bmBce0na8kCdoCUkKzl/xuQ==} + + '@datadog/browser-logs@6.24.1': + resolution: {integrity: sha512-SmqUVzif6IRrdkhh8mewfFa64IfcnkPXLgMYigJDzo7O1f8PEuHF63sDJ2/x2hTXR68e2JKBKE/ooFpAmtCnYw==} + peerDependencies: + '@datadog/browser-rum': 6.24.1 + peerDependenciesMeta: + '@datadog/browser-rum': + optional: true + + '@dynamic-labs-connectors/base-account-evm@4.7.1': + resolution: {integrity: sha512-cltg1IBdcbJt+fgoBLH86AfmNlgurWOllLZ6ngcmvSlebNvaCmXc2yvhUCrr4YKpwqkmGUdt+5RQdNJYkXb9MA==} + peerDependencies: + '@dynamic-labs/ethereum-core': ^4.88.7 + '@dynamic-labs/wallet-connector-core': ^4.88.7 + viem: ^2.21.55 + + '@dynamic-labs-connectors/metamask-evm@4.7.1': + resolution: {integrity: sha512-/7CaVI53j6FB2HBppM/97TreQ/tq7pSRqA8SACZeI0myXm2wMQgn3dptNH2g/bBZ+KohUHO7CdIEaeQ1jFl7Ng==} + peerDependencies: + '@dynamic-labs/ethereum': ^4.88.7 || ^5.0.0 + '@dynamic-labs/ethereum-core': ^4.88.7 || ^5.0.0 + '@dynamic-labs/wallet-connector-core': ^4.88.7 || ^5.0.0 + viem: ^2.21.55 + + '@dynamic-labs-connectors/metamask-solana@4.7.1': + resolution: {integrity: sha512-u+Kp/gwL/7kIrhWt+MzRzDZu8JF40Tox5EFMLMDnCKbdP9MSMQ8ckMBiQUkBRulC6nGfN3Gut4bpiwdWpQHzKQ==} + peerDependencies: + '@dynamic-labs/solana-core': ^4.88.7 + '@dynamic-labs/wallet-connector-core': ^4.88.7 + '@solana/web3.js': '>=1.0.0' + + '@dynamic-labs-sdk/assert-package-version@1.39.1': + resolution: {integrity: sha512-QiQKcJPK4piu+WdmZTnk8qTgPhcUuCKmNqd32RgBNLwn8AEQ36FWsPE+y7RXPg7yO3u67QokKUKHkrV3lxDstA==} + + '@dynamic-labs-sdk/client@1.39.1': + resolution: {integrity: sha512-h+5t9g9t+rqMkhC8kgrgscAlIZTmyUwvMRbiQEGZidLLqFBd5M6qoYmOr9p6wnD2g389eSpYlNfLh7lJwkhlRg==} + peerDependencies: + '@react-native-async-storage/async-storage': ^2.2.0 + react-native: '>=0.73.6' + react-native-inappbrowser-reborn: ^3.7.0 + react-native-keychain: ^10.0.0 + react-native-passkey: '>=3.3.2' + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + react-native: + optional: true + react-native-inappbrowser-reborn: + optional: true + react-native-keychain: + optional: true + react-native-passkey: + optional: true + + '@dynamic-labs-wallet/browser-wallet-client@1.1.33': + resolution: {integrity: sha512-YEDQFnlDnnNdY8gGDmLgFlhe39PpPbArqPN7aZkDU0SE9M11NbSdSZdV7diDAi8x+4db+DUKW0ke6oUE3+N62A==} + + '@dynamic-labs-wallet/core@1.1.33': + resolution: {integrity: sha512-NehhQyiR9Xl9AkfhmNcLtyR54J0CKva5Rfn6RWit1juODbLfZLsh4o6BWUy6zG23rIsj50FTAEpZCi5bIIN2ew==} + peerDependencies: + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2 + + '@dynamic-labs-wallet/forward-mpc-client@2.0.2': + resolution: {integrity: sha512-DUdwqhYTEGoz3wMW4PmOl4tyw5IkTGB3n3KAgLMM6UkDWPsYzH5C4hkjbb6ZQdsHqF99kmoU5gsMcylJ41bYLA==} + peerDependencies: + '@dynamic-labs-wallet/primitives': '>=0.0.336 || 0.0.1' + + '@dynamic-labs-wallet/forward-mpc-shared@0.7.2': + resolution: {integrity: sha512-C5ugG0QNL1FNoFNCo3A2Hz3h1boycoC6S5jh5GoQmVTz7/MNKAgsnYRyd/xC7a9UIiZtwr6vttXvTLxMnx/q4A==} + peerDependencies: + '@dynamic-labs-wallet/primitives': '>=0.0.336 || 0.0.1' + + '@dynamic-labs-wallet/primitives@1.1.33': + resolution: {integrity: sha512-RAgm/QL10EZ4RjJSehgf2OzUe0heAvp9SF9FJKL0eqiwjLWjsAfOh3Pl8cGpgw1bzyPGnoxr07qY8DkXaXtpFA==} + + '@dynamic-labs/assert-package-version@4.100.5': + resolution: {integrity: sha512-bST4as2Y/t46xUnLz/FvX/S9UJPL0WOo825Jm3Fjt4IbLBKK8OurCwK1NSTpiliRtC6LMCngWAXhCHS3WQTv3A==} + + '@dynamic-labs/assert-package-version@5.13.0': + resolution: {integrity: sha512-Yz8nUpsH/IT4lmQmqaeknP1DGVd5cm4Y7lqumh1MIZ6969eAirz3z0dE7DI8LGltcQSizGUWhDdqux3d9x+k7Q==} + + '@dynamic-labs/embedded-wallet-evm@4.100.5': + resolution: {integrity: sha512-9OgkJxb1l6d4oHwiG9DepqOYtJiSFfLYagHe8ENSoSEAd0cKlRcmoSWsGoUHCtMd1v7uavL+Dx9ajjW8ebmQrA==} + peerDependencies: + viem: ^2.45.3 + + '@dynamic-labs/embedded-wallet-solana@4.100.5': + resolution: {integrity: sha512-utaN4ke1cBOVZVTLqp0Rz7NzEt7JhG3F6cnL0dwAR7u2bVMxmkKRi5BzvkPmhQenZMGwJwQLOfv4nMrwYJxEsg==} + + '@dynamic-labs/embedded-wallet@4.100.5': + resolution: {integrity: sha512-LU8S+aa9qeIbZCZ6Pxn4hIcRnGuscXhsQBVzTAYm3nLcvmUYAhJRsvlyFscMughb2Ox3zIQVc1M+8IPaQzhrJQ==} + + '@dynamic-labs/ethereum-core@4.100.5': + resolution: {integrity: sha512-rzk2d6eHpgq1k8Qqz1kDRjrlG6kIbhFKO1QRuX+GthHgsyDePpm+ddi7oBQPfr6iX408iCzlU4Om/U1Yw9O4RA==} + peerDependencies: + viem: ^2.45.3 + + '@dynamic-labs/ethereum-gasless-core@4.100.5': + resolution: {integrity: sha512-5iw5s5gdfPCqFO/t6630S7HLm9enRFU8+fPEk9QLZuxkRql0zZHxqmiiSHTe2VH6J2oWk5ihbikIlxaTZY4m4w==} + peerDependencies: + viem: ^2.45.3 + + '@dynamic-labs/ethereum@4.100.5': + resolution: {integrity: sha512-H1iaR4QUOL56xS7kJ98gjdcgHpAO2TemFdjrZcgEYhIwZT7UaeyiwQdch7aJufDtt86881NYRwe/xVdGcZvYfQ==} + peerDependencies: + viem: ^2.45.3 + + '@dynamic-labs/iconic@4.100.5': + resolution: {integrity: sha512-/IbtQXavqfDGYVFVMfYeWBOjJKEIARYEU7NBya1En0odmIqDi2ka1G9kAHdhoqkyzxYHa8YXaBbbMrcquGII9A==} + peerDependencies: + react: '>=18.0.0 <20.0.0' + react-dom: '>=18.0.0 <20.0.0' + + '@dynamic-labs/locale@4.100.5': + resolution: {integrity: sha512-z2H1gXVtX17ZqFUu51GXkbDjLTiGu9EPqN3WqD39DGA7Z91d0OE9Pn6k0tRm+fGBKiH+OtoMr/4ZIiwC9diRyg==} + + '@dynamic-labs/logger@4.100.5': + resolution: {integrity: sha512-eOK1cI5wQ20DAul499k1rOV89w5MN6+T7E9RPpGxXQ80ZhqOspqGiQK/H+Yh7XxjqVMbZ4EJIy0k8VeNwHuSew==} + + '@dynamic-labs/logger@5.13.0': + resolution: {integrity: sha512-UkX7DmFGPVcxpeHflg5cv8O9TtheGRq6kKMYK53lNMAqDsuTIdlaWStRWB2jJCpWF4Cj7MQkLGGTNoVVIi0ZeQ==} + + '@dynamic-labs/message-transport@5.13.0': + resolution: {integrity: sha512-hZ2aPBMebKQL0/gTiXnyIHU8GPU+C+m73VzrZHCQ4xoJ0sxoZTja/jtnbvCUfPsLtMfdHrrv2tTUGWA5GAHceg==} + + '@dynamic-labs/multi-wallet@4.100.5': + resolution: {integrity: sha512-qgvKdWLW85YdOlwqfZcSB0fSBvGuNryE0pv+zVoU6R+mRpm9gAMQ9zFZhnP54pvBpyZGnhKcBS9MkU1QhFu2PA==} + + '@dynamic-labs/redaction@1.1.0': + resolution: {integrity: sha512-y3ixDtS4N+ZEgQC17k3d3oyxZ5BJ+sAGvQRklXCilwYkWOMwtMc6QEx/5uHz1PS/rxWYuZk+Egr1AC5NuzZLrg==} + + '@dynamic-labs/rpc-providers@4.100.5': + resolution: {integrity: sha512-HyQQTRVvFNFohUgDqQ1cqeyX6xIDknsEVlbx0xnvx4OwhkNHYyAdZP42AfkyDaTE8uXhf/JA1qFk4Gj3URIi3g==} + + '@dynamic-labs/sdk-api-core@0.136.0': + resolution: {integrity: sha512-dQwmQQQeYGcPgk53lGfnghVC9QMK5BxOA5LPHVn5+HjebuDClq8QWTYoihY0dM3bX8xf68R2W4dgRvh4B3VcvA==} + + '@dynamic-labs/sdk-api-core@0.50.0': + resolution: {integrity: sha512-qdOdnBDB/q8zfe22jQr+4wBiKcawaLNxYJGNxMs5n+tF4jh2F98ZMv0JiJXPRc/W4jpnjgTNfEAfQErcpaxoOQ==} + + '@dynamic-labs/sdk-api-core@0.92.0': + resolution: {integrity: sha512-5ABRxs5KLbdKZ9yA/kF7wa7rimKMQLxr5yz6bwFW+L0k7quUepYFwKQeIxgqecVuGmnq3WeFoc/l9MY90s3XKw==} + + '@dynamic-labs/sdk-react-core@4.100.5': + resolution: {integrity: sha512-ckDYKc2zeGadng5WMBUFYyXiqqEdSm17gYwMoseqRkfjCPatQBG6QvkUzKVx1gSPP16CayUX3aORhByZkPOriw==} + peerDependencies: + react: '>=18.0.0 <20.0.0' + react-dom: '>=18.0.0 <20.0.0' + + '@dynamic-labs/solana-core@4.100.5': + resolution: {integrity: sha512-5qNrLlUtFW0L1sLhi6vuLvwnyUCCuqw2eyRLrH0Q9ZWpvYT3pevdCYAS5aoL55aKzZ1H+kGMAphxdzKfKzrCjw==} + + '@dynamic-labs/solana@4.100.5': + resolution: {integrity: sha512-0mr1zd05BLQgmAYwpAQuqqtu/a/cFeT/aq0j6abJFrP30Nnm3xeAQejgP9HpEhVQPIzOEHb9K6Wzs40E46oeDg==} + + '@dynamic-labs/store@4.100.5': + resolution: {integrity: sha512-pfHZ9efW4uP+0ANSUwo0t2xWD2IIDyY0dqhMfBmnmM7Jh5JD4GUwssZi8C7cGAkpVhSd9MKV3S1vhmpI59UhTA==} + + '@dynamic-labs/sui-core@4.100.5': + resolution: {integrity: sha512-H+qEl7fDQ9uCpOpSve1B1nglGjZR1nQxZvSg0WfAYRftU3TKTBu+zzCEcO0HEQFBYc18OxHujc6e5ECHXKvTvQ==} + + '@dynamic-labs/sui@4.100.5': + resolution: {integrity: sha512-CKXi+71KNAITi8eayK/VCztgTGNtbqR2KM4AK7cvrWH6Tp16gp/J2KSkQX37nzwbqpO62croKjkXHarJVa7E8w==} + + '@dynamic-labs/types@4.100.5': + resolution: {integrity: sha512-2F1CSxfYxNxkpdwJ+Hlr2/O/P/vYHb7KBi1xOg7FZizVq8zOx0YCW8iEtQ4z1SuCzZ5gac4lSRs2uuOj2D2+Zg==} + + '@dynamic-labs/types@5.13.0': + resolution: {integrity: sha512-qVZV0vKOlOY4zzOcpPyu23FJ3LQpidNIvdQ23TV4EeWSXbk3snRYTUz3DPVJ8h6/P/8K8SxDiAZY4GP4NzNM6A==} + + '@dynamic-labs/utils@4.100.5': + resolution: {integrity: sha512-3csnU31aISjwgA1QXRtcvOqak/82SC5oQFHj4uvktfLjPMqSzg83C11d0X/1WD9S2K3XhqPEWqDxFfpxwCxvvw==} + + '@dynamic-labs/utils@5.13.0': + resolution: {integrity: sha512-F5yZD6gUEuHO7rAhLSkcQAkLbh8idQid6bYp8Pxo+mgLOQ83pPb7v8lacvi5BLh59nWmbASGNyt65FPrpelJnw==} + + '@dynamic-labs/waas-evm@4.100.5': + resolution: {integrity: sha512-EEHG226vDKsx1/b2qD+P8oYQwybLSg2+ej/Ars70Rt4hu3Cx1os+8db3dShc4BeHznQkPn/vwi53nuAJxy8OwA==} + + '@dynamic-labs/waas-sui@4.100.5': + resolution: {integrity: sha512-ABSuP2WHUAhJdI2fGE7TbjJyKNWQY7/Z+rBfvyzaiGngvZ9Tt+8aPjL4No8ksTa+mb7BF2qoKBCQfLNs54DPvA==} + + '@dynamic-labs/waas-svm@4.100.5': + resolution: {integrity: sha512-fz+JVc+VRpCyq+VsrJY5txwAZcx/ducsGLkSUioCsRwhmZOF5Yjo1TD/eenkEMAti9B3FDQtkWurdRu4MxoFsQ==} + + '@dynamic-labs/waas@4.100.5': + resolution: {integrity: sha512-oOUBfDde1Nw4kDtToecaBkrR9MLMXANGcAcYzjzaCbgMHMp9j8cNAOZ2pgV9JPG2C6iHTfJAAeaOk+GXopWq1w==} + + '@dynamic-labs/wallet-book@4.100.5': + resolution: {integrity: sha512-cXtNumBHNa6A6g1ktDn0wsl2EXAnkwoX43ufGquyP9Rszw7k3/BwTrCW+81+lAQ3oQV48fumk9CX1zpthUlOIg==} + peerDependencies: + react: '>=18.0.0 <20.0.0' + react-dom: '>=18.0.0 <20.0.0' + + '@dynamic-labs/wallet-connect@4.100.5': + resolution: {integrity: sha512-lfkLYbJaV9R3K2TN8Mozd+Q/60iGTLYLpe4F/7iMSrbEIjlyGX6wLBEGD18DlL+AdYAgkefAgmgcqLKPzfj1dA==} + + '@dynamic-labs/wallet-connector-core@4.100.5': + resolution: {integrity: sha512-i+jQioIUvbo0DbQXowU+RYfmZEwfGP8lBLGSMUwq/i6/HH54Ojqg1cl800AFJVW6ntSUWMbjWk/SE+oSvZ7g5A==} + + '@dynamic-labs/webauthn@4.100.5': + resolution: {integrity: sha512-DZSbprKmmcOMmefP/Msc1xfauNfPypwb5o0aJ1nKkNhkv2MRxk8zrNfprzhVtp/u/Gy3YrAdGWywVgZX1H+TvA==} + + '@ecies/ciphers@0.2.6': + resolution: {integrity: sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g==} + engines: {bun: '>=1', deno: '>=2.7.10', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} @@ -204,6 +490,60 @@ packages: '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emotion/babel-plugin@11.13.5': + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + + '@emotion/cache@11.14.0': + resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} + + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + + '@emotion/react@11.14.0': + resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + + '@emotion/sheet@1.4.0': + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + + '@emotion/styled@11.14.1': + resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/unitless@0.10.0': + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0': + resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + peerDependencies: + react: '>=16.8.0' + + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + + '@emotion/weak-memoize@0.4.0': + resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + '@esbuild/aix-ppc64@0.28.2': resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} engines: {node: '>=18'} @@ -404,6 +744,80 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@evervault/wasm-attestation-bindings@0.3.1': + resolution: {integrity: sha512-pJsbax/pEPdRXSnFKahzGZeq2CNTZ0skAPWpnEZK/8vdcvlan7LE7wMSOVr+Z+MqTBnVEnS7O80TKpXKU5Rsbw==} + + '@gql.tada/cli-utils@1.9.4': + resolution: {integrity: sha512-xQ9M+2Xxjxhz9IJi+7IMU/aOsEtuSiSNb4OgDMBUC/8AcSpo2vDtx71Aodsaif4qSwuTb0YFVfDwC+ESqiZSHg==} + peerDependencies: + '@0no-co/graphqlsp': ^1.16.0 + '@gql.tada/svelte-support': 1.0.3 + '@gql.tada/vue-support': 1.0.3 + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@gql.tada/svelte-support': + optional: true + '@gql.tada/vue-support': + optional: true + + '@gql.tada/internal@1.2.2': + resolution: {integrity: sha512-4lZcElPP6MC8Ct8KN70LR2WQsHjbAsyAmTGG09VsOPhx738UFIYaL0S1XiI2pqq2tj/sDs/y3b9jvKoWGL7iuQ==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@hcaptcha/react-hcaptcha@1.4.4': + resolution: {integrity: sha512-Aen217LDnf5ywbPSwBG5CsoqBLIHIAS9lhj3zQjXJuO13doQ6/ubkCWNuY8jmwYLefoFt3V3MrZmCdKDaFoTuQ==} + peerDependencies: + react: '>= 16.3.0' + react-dom: '>= 16.3.0' + + '@hey-api/client-fetch@0.8.1': + resolution: {integrity: sha512-AaVNVLBl7N9Fun7QDnb00YDubAFjB9ICi5U6kmzcJSnnQTQGRMsuBBRupQV5ERdMMFt71zjSDym7Z+gLVe8m3A==} + deprecated: Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts. + + '@hpke/chacha20poly1305@1.8.0': + resolution: {integrity: sha512-FcBfAQ+Y99vMNJP2yrZ9wpL8V0GOwp1+zMyzvc6alasrBygfFjFm1yeUtyADJCu/27C3Lm5mJzx6u7pwg+cX5w==} + engines: {node: '>=16.0.0'} + + '@hpke/common@1.10.1': + resolution: {integrity: sha512-moJwhmtLtuxiUzzNp1jpfBfx8yefKoO9D/RCR9dmwrnc7qjJqId1rEtQz+lSlU5cabX8daToMSx/7HayXOiaFw==} + engines: {node: '>=16.0.0'} + + '@hpke/core@1.9.0': + resolution: {integrity: sha512-pFxWl1nNJeQCSUFs7+GAblHvXBCjn9EPN65vdKlYQil2aURaRxfGMO6vBKGqm1YHTKwiAxJQNEI70PbSowMP9Q==} + engines: {node: '>=16.0.0'} + + '@hpke/dhkem-x25519@1.8.0': + resolution: {integrity: sha512-S1MWWkAfu+TFxySgv5+2P3O4Mx/jk7BsoplzQaA1s3sfUJVJ2UsZsSzSsMc+FXJumLXncoJFlO6mK6mDGspfmA==} + engines: {node: '>=16.0.0'} + + '@hpke/dhkem-x448@1.8.0': + resolution: {integrity: sha512-mFfnZfgp4OKkUIS/FKikfUgdnDKRy25ytCKBQiV+N+HbYy3I4v4ZCPBQ69QL+TYmKmCZJeUEnYeS5K+OBRP+Eg==} + engines: {node: '>=16.0.0'} + '@humanfs/core@0.19.2': resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} engines: {node: '>=18.18.0'} @@ -428,81 +842,163 @@ packages: resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} + '@img/sharp-darwin-arm64@0.35.0': + resolution: {integrity: sha512-ZgaYEwaj+lx/5n4W8GmZ2IYz0PQHjN5eqRcfijWGB+2Aq7ZInZGa0qJyAn6DEtyLuWHRSrmWOqT9q3qqTBvmUQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + '@img/sharp-darwin-arm64@0.35.5': resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [darwin] + '@img/sharp-darwin-x64@0.35.0': + resolution: {integrity: sha512-c1z9LFpKB0slQW3RchwBE8iSVzGp70TNjUUO9k4BZwwW4HH7JBGHeIy4b+kk4n/kcBASb9evKCE3/7Slmslgiw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + '@img/sharp-darwin-x64@0.35.5': resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==} engines: {node: '>=20.9.0'} cpu: [x64] os: [darwin] + '@img/sharp-freebsd-wasm32@0.35.0': + resolution: {integrity: sha512-Li2KTev0H90kEtnJHkI9xQojXt1AqWmFBMXiPw5kqd1jQgP7gi5HVK/qC5Rmh/59NuAwUuPzzPITmX22NomYYQ==} + engines: {node: '>=20.9.0'} + os: [freebsd] + '@img/sharp-freebsd-wasm32@0.35.5': resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==} engines: {node: '>=20.9.0'} os: [freebsd] + '@img/sharp-libvips-darwin-arm64@1.3.0': + resolution: {integrity: sha512-EKbmBKtyTH+GPFDRw2TgK2oV6hyxxlJVIar4hoTYSNmIwipgMFdxPQqR392GmfdsPGWga0mCFN1cCKjRb9cljw==} + cpu: [arm64] + os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.3.4': resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==} cpu: [arm64] os: [darwin] + '@img/sharp-libvips-darwin-x64@1.3.0': + resolution: {integrity: sha512-Pl2OmOvrJ42adUllESxBsG54PfXLo1OYg9i3c5/5Ln/qJ0gZuTM9YMhQJPIbXqwidLRc/c2zuHt4RsrymmNv7A==} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-darwin-x64@1.3.4': resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==} cpu: [x64] os: [darwin] + '@img/sharp-libvips-linux-arm64@1.3.0': + resolution: {integrity: sha512-C0SqjoFKnszqa44EQ7xoaT48nnO0lOyXEULfXMWi8krrjOPGYkeK30Okzla6ATbBYsyZ0ySinK0FVkpv3DwzfQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-arm64@1.3.4': resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==} cpu: [arm64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-arm@1.3.0': + resolution: {integrity: sha512-A8UpHoUDW4DwnXoV6+q3C1s7QLRAHtPDEjWuNZjwHMyoCNZnm0GeNN8ls9f/bsEYTRQRW96C/n34XJQHJ2fT7A==} + cpu: [arm] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-arm@1.3.4': resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==} cpu: [arm] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-ppc64@1.3.0': + resolution: {integrity: sha512-WOpkVxAjFd369iaIzEgNRreFD+gWdUMIGD5zplhNKNeqS6mm5dac3q2AFyCBmzYoAdouzZvRBgxy4z8QHZb4/A==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-ppc64@1.3.4': resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==} cpu: [ppc64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-riscv64@1.3.0': + resolution: {integrity: sha512-DRWw0mOHusrCCuw2rqP87oLg6PGlkomVDFqw2hIwsSfwWpu4k3XLcBPaKKl6ct/GtL/cwNkgwjV/tc0Mqht3VA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-riscv64@1.3.4': resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==} cpu: [riscv64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-s390x@1.3.0': + resolution: {integrity: sha512-9APy+nFWhHS+kzLgWZfLcyrUd7YqnAQVa4BPOo4xkoHpdoktOAPG4cEr9+Jpl0TtqfVmcMJimNL5qNTyyOHZNA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-s390x@1.3.4': resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==} cpu: [s390x] os: [linux] libc: [glibc] + '@img/sharp-libvips-linux-x64@1.3.0': + resolution: {integrity: sha512-y9RNUYDe2A1UAdhLyfeOodGRszQdaEoe4nfOpp/sNVPl2CWIcUyFaDoCh4vPLPxu19803j2naLqZup2WxDXCLA==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@img/sharp-libvips-linux-x64@1.3.4': resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==} cpu: [x64] os: [linux] libc: [glibc] + '@img/sharp-libvips-linuxmusl-arm64@1.3.0': + resolution: {integrity: sha512-cC1wkC0Mlucd0KSiGrLkJnB/ZqPvZCntc/Lk7ZnYO5ZSbF2euNek4Xvxafojq+wN1q/W0eprdpUIjUr/EV2PBg==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==} cpu: [arm64] os: [linux] libc: [musl] + '@img/sharp-libvips-linuxmusl-x64@1.3.0': + resolution: {integrity: sha512-LiYMhUZicB1QG//+RvmYZpXJO8fYRENfp+MZUCnG9aw+AKvGAy9gPaCnuwsPcBFs8EV66M0NNxj9VHcNklE8zw==} + cpu: [x64] + os: [linux] + libc: [musl] + '@img/sharp-libvips-linuxmusl-x64@1.3.4': resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==} cpu: [x64] os: [linux] libc: [musl] + '@img/sharp-linux-arm64@0.35.0': + resolution: {integrity: sha512-4+4XHLNT5wDT0roYlHTEmH9lDKt0acf9Tv+3hM3iceOirkxrR404/3WjAYZ9F9CkHrxeRcGLJXbi4vluMZ9O+A==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-arm64@0.35.5': resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==} engines: {node: '>=20.9.0'} @@ -510,6 +1006,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-arm@0.35.0': + resolution: {integrity: sha512-VVlpEWwizEFIOom0zdoeKuO5nuTswzVE5uHcBNvHzmeHUpNFajY3HFfbQ+zIH4E2kVaZ/yVxmsShW56TtEy4uA==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + '@img/sharp-linux-arm@0.35.5': resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==} engines: {node: '>=20.9.0'} @@ -517,6 +1020,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-ppc64@0.35.0': + resolution: {integrity: sha512-N3hzbEpUTJC8pWpPVJvgzGxM+so/MAXc8O2s/53B0LL9ZGpfXpME7Wizkc5d/8fRBlBtkDjzoZGDCqqNDHqLEw==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-ppc64@0.35.5': resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==} engines: {node: '>=20.9.0'} @@ -524,6 +1034,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-riscv64@0.35.0': + resolution: {integrity: sha512-l6vmKVPnbS0RhVMbyxP5meAARsbhCnBN4fy31qz0+3a6Rv4jEqfzDrT89y6ZPkCi0AJGnwp2En528yXo401Hpw==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-riscv64@0.35.5': resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==} engines: {node: '>=20.9.0'} @@ -531,6 +1048,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-s390x@0.35.0': + resolution: {integrity: sha512-MYlMiPFiv/EKPAHnp3yNZ9AAWFsxga9c5Bkc6wkar6bqzHLlkGVJHRm0u1ei+VXnZxp3Mz9MG9ZIsI8vSOf3sQ==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@img/sharp-linux-s390x@0.35.5': resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==} engines: {node: '>=20.9.0'} @@ -538,6 +1062,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linux-x64@0.35.0': + resolution: {integrity: sha512-TYaItB5oj1ioXjhyn2xrR208vf+YuIIcHptQWRRaBmFhvIvL9D72DXN8w75xup0KXA8UdEAhQ9Qb2S49FD/9Cw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + '@img/sharp-linux-x64@0.35.5': resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==} engines: {node: '>=20.9.0'} @@ -545,6 +1076,13 @@ packages: os: [linux] libc: [glibc] + '@img/sharp-linuxmusl-arm64@0.35.0': + resolution: {integrity: sha512-DSTb6ijQzqe6DdAaOBVqJ/SYf1vO8EW5bK6X6LRXufEBebf2722VCdvBUtZ3rtV0x2ApfPNDy/p7LrrjaWjiyQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + '@img/sharp-linuxmusl-arm64@0.35.5': resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==} engines: {node: '>=20.9.0'} @@ -552,6 +1090,13 @@ packages: os: [linux] libc: [musl] + '@img/sharp-linuxmusl-x64@0.35.0': + resolution: {integrity: sha512-K7ykQ+26Rt6+4BTU80AuGgTPIYX86UxiAKT4rcXX/WNTo7k1ZxpKz+TguHnwVpCqQK3B5PK0vZ0ZBe6nz/ib1w==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + '@img/sharp-linuxmusl-x64@0.35.5': resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==} engines: {node: '>=20.9.0'} @@ -559,27 +1104,54 @@ packages: os: [linux] libc: [musl] + '@img/sharp-wasm32@0.35.0': + resolution: {integrity: sha512-9woLIFORERCr+6cWu87dQ22J34EExkhc73U1kZW0c+RclQqWetoodByp4dWZ/hN8/KVmTRAx2HOnUwib8AwZdA==} + engines: {node: '>=20.9.0'} + '@img/sharp-wasm32@0.35.5': resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==} engines: {node: '>=20.9.0'} + '@img/sharp-webcontainers-wasm32@0.35.0': + resolution: {integrity: sha512-t+kie1TOyaDM6Dho+f+y0VqIUNhYQaKCUahuZVi0E0frgdiaOaPsDxDW3wfKacUdaNBCnK/ZDBMg33ydvHj8uA==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + '@img/sharp-webcontainers-wasm32@0.35.5': resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==} engines: {node: '>=20.9.0'} cpu: [wasm32] + '@img/sharp-win32-arm64@0.35.0': + resolution: {integrity: sha512-M5eKxug0dabbaWgFKvPa3odNs2OpaP+81NASfGKkt4GcYXpNhSu7CaeYxWkLNV6vHmUp4hnCxnxrUyhUJhXbKA==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + '@img/sharp-win32-arm64@0.35.5': resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [win32] + '@img/sharp-win32-ia32@0.35.0': + resolution: {integrity: sha512-z0+pZ03QCDvdVN0Ez9IX/yjWC19ikMlXrmdYMwYNLTh2BLPx3hXWPvyqWfquZ0BTO9O6GVOjIVoTcyyacMnWlQ==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + '@img/sharp-win32-ia32@0.35.5': resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==} engines: {node: ^20.9.0} cpu: [ia32] os: [win32] + '@img/sharp-win32-x64@0.35.0': + resolution: {integrity: sha512-feNnlz5ZHKr0MY1LPHvZQyJeBkbo4ctsn0D8FvA53VTw5TC63rfEL2UrWbkSBR19htSE7Mw78xYVwdJqoMWVHw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + '@img/sharp-win32-x64@0.35.5': resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==} engines: {node: '>=20.9.0'} @@ -602,6 +1174,113 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@lit-labs/ssr-dom-shim@1.6.0': + resolution: {integrity: sha512-VHb0ALPMTlgKjM6yIxxoQNnpKyUKLD04VzeQdsiXkMqkvYlAHxq9glGLmgbb889/1GsohSOAjvQYoiBppXFqrQ==} + + '@lit/react@1.0.8': + resolution: {integrity: sha512-p2+YcF+JE67SRX3mMlJ1TKCSTsgyOVdAwd/nxp3NuV1+Cb6MWALbN6nT7Ld4tpmYofcE5kcaSY1YBB9erY+6fw==} + peerDependencies: + '@types/react': 17 || 18 || 19 + + '@lit/reactive-element@2.1.2': + resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} + + '@marsidev/react-turnstile@1.5.2': + resolution: {integrity: sha512-+3aBPxp86JzSC0ZmgyonoGoUEENcUkH3LGahXSpkV87ArvD2DzRCmPgh0FyQk6PQRmJwQJDAfwNavFsxUxMQWA==} + peerDependencies: + react: ^17.0.2 || ^18.0.0 || ^19.0 + react-dom: ^17.0.2 || ^18.0.0 || ^19.0 + + '@metamask/analytics@0.6.0': + resolution: {integrity: sha512-L250lV3PANTcKqhZkmRV1Obkyddm6JDQvDBuUVAi+7TmPdOVdpavWNXyEh7ErscjwG0z2wiF9Ne0ihK/nCdX0w==} + engines: {node: '>=20.19.0'} + + '@metamask/connect-evm@2.1.0': + resolution: {integrity: sha512-u0eYWPGWOk9w7ne+dAynO0saN2mCXfkt1QLGo829kiDLO0YGuFSNXWpRxnIygm6j9s9NOVLkL7+tkyZCR755Jw==} + engines: {node: '>=20.19.0'} + + '@metamask/connect-multichain@1.1.0': + resolution: {integrity: sha512-PywCTfcSkLHTkEYhnrQbQPv/6laXTPKLmVlJnCAkqFon0jxX6ETCthZcA30fwUQhiOONmG5/MZano3imH+K5dA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@react-native-async-storage/async-storage': ^1.23 + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@metamask/connect-multichain@1.2.0': + resolution: {integrity: sha512-EoRXtP8cpLhY/YRlQ8rSjzYrc+ykJjMYPL6sF2U9b8Ron9yAVjZCPfSftBjee/tXxQDJ8BupmZbkv4af/vVuSQ==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@react-native-async-storage/async-storage': ^1.23 + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@metamask/connect-solana@2.1.0': + resolution: {integrity: sha512-cse70fsY0ObINGytj2bskx25Xb6pOKJAGBO/PW1jAMEFI+xijlHznGo1vsON14dUKJKyiZyCoTSxrA40NlNB8w==} + engines: {node: '>=20.19.0'} + + '@metamask/mobile-wallet-protocol-core@0.4.0': + resolution: {integrity: sha512-rB1wMogvSUsFaxyH/eVUCczIkTxVaPPETlD/wgm+gw7EbWP0LlZPY7Bh+DICSfUCJ0zqnoFuwr77WNJvZ6ZiWw==} + engines: {node: '>=20'} + + '@metamask/mobile-wallet-protocol-dapp-client@0.3.0': + resolution: {integrity: sha512-rXStrvIa57a8OaeM+3HeR6Z9ETHOvmQi/9s6CLplDwH2hn2MWjI6WW3EUrxq2KGmGuhbO5Oo21ANnD23QKfduw==} + engines: {node: '>=20'} + + '@metamask/multichain-api-client@0.10.1': + resolution: {integrity: sha512-LsqO2SiDcTgOuXyVYEB0zgBaVNhryhP2tYI3L7tLa7PoeDqMkNIreFhDeu8jM5tPWkCimQvMwCkG3DF4P5dD3A==} + engines: {node: ^18.20 || ^20.17 || >=22} + + '@metamask/multichain-ui@0.4.1': + resolution: {integrity: sha512-tJgTot8Pfkda895A6biJu7rE+jlQdVCNVzGgW+2wM9aFG20G+GEbQy3KO7uC4ImUvaKV4SyJ45r6Ir/Yf55mqw==} + engines: {node: '>=20.19.0'} + + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + + '@metamask/rpc-errors@7.0.3': + resolution: {integrity: sha512-nrEaeBawm8yFU7hetJKok/CUs0tQsWtTqp3OLbFhPUMXYqU7uI5LAV5vi9o7rTjFkUyof7Nzbw5bea5+1ou+dg==} + engines: {node: ^18.20 || ^20.17 || >=22} + + '@metamask/scure-bip39@2.1.1': + resolution: {integrity: sha512-1K8aBsAqr6+8jWhguVl06n8e+zjV9sUnys+5PLyVU4mb8LbulQ60F6cq7iQys3xX/yCwKt1+7c7j2nuTEpW+ZQ==} + engines: {node: ^16.20 || ^18.16 || >=20} + + '@metamask/solana-wallet-standard@0.6.0': + resolution: {integrity: sha512-gF763JvLIywPttw+vfRdZx0uHlB0sEbxOGFedblMk78SbQ/KyQrmjHRkFVVrG21oLZgCNEh3uQpCWBdW2+eUzw==} + engines: {node: ^18.20 || ^20.17 || >=22} + + '@metamask/superstruct@3.4.1': + resolution: {integrity: sha512-caTaaBUcwBGbUNf3r0uT48upX4nECRbKhQ9pPOfW4sIkfcIUUDV4S9DZxq/5fuNPVt5KWpyd5xIIz0sP+iWLlg==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@11.12.1': + resolution: {integrity: sha512-X97J5AEcaKDTIAfKb4X93ZTLfvOahzDVadlveQW+7OZ7yhXjMxXoFmhX2d9UKv48iS2Dxq9kbGJ1lUfphu9ebQ==} + engines: {node: ^18.18 || ^20.14 || >=22} + + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} + + '@msgpack/msgpack@3.1.2': + resolution: {integrity: sha512-JEW4DEtBzfe8HvUYecLU9e6+XJnKDlUAIve8FvPzF3Kzs6Xo/KuZkZJsDH0wJXl/qEZbeeE7edxDNY3kMs39hQ==} + engines: {node: '>= 18'} + + '@mysten/bcs@1.9.2': + resolution: {integrity: sha512-kBk5xrxV9OWR7i+JhL/plQrgQ2/KJhB2pB5gj+w6GXhbMQwS3DPpOvi/zN0Tj84jwPvHMllpEl0QHj6ywN7/eQ==} + + '@mysten/sui@1.45.2': + resolution: {integrity: sha512-gftf7fNpFSiXyfXpbtP2afVEnhc7p2m/MEYc/SO5pov92dacGKOpQIF7etZsGDI1Wvhv+dpph+ulRNpnYSs7Bg==} + engines: {node: '>=18'} + + '@mysten/utils@0.2.0': + resolution: {integrity: sha512-CM6kJcJHX365cK6aXfFRLBiuyXc5WSBHQ43t94jqlCAIRw8umgNcTb5EnEA9n31wPAQgLDGgbG/rCUISCTJ66w==} + + '@mysten/wallet-standard@0.19.9': + resolution: {integrity: sha512-jHFt+62os7x7y+4ZVMLck8WSanEO9b8deCD+VApUQkdAHA99TuxbREaujQTjnGQN5DaGEz8wQgeBPqxRY/vKQA==} + '@napi-rs/wasm-runtime@1.2.5': resolution: {integrity: sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==} engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} @@ -667,6 +1346,72 @@ packages: cpu: [x64] os: [win32] + '@noble/ciphers@0.4.1': + resolution: {integrity: sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.0': + resolution: {integrity: sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.2': + resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.4': + resolution: {integrity: sha512-2bKONnuM53lINoDrSmK8qP8W271ms7pygDhZt4SiLOoLwBtoHqeCFi6RG42V8zd3mLHuJFhU/Bmaqo4nX0/kBw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@2.0.1': + resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} + engines: {node: '>= 20.19.0'} + + '@noble/hashes@1.3.3': + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} + + '@noble/hashes@2.4.0': + resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==} + engines: {node: '>= 20.19.0'} + + '@noble/post-quantum@0.5.4': + resolution: {integrity: sha512-leww0zzIirrvwaYMPI9fj6aRIlA/c6Y0/lifQQ1YOOyHEr0MNH3yYpjXeiVG+tWdPps4XxGclFWX2INPO3Yo5w==} + engines: {node: '>= 20.19.0'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -697,9 +1442,84 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} + '@openzeppelin/contracts@4.9.6': + resolution: {integrity: sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==} + '@oxc-project/types@0.153.0': resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==} + '@paulmillr/qr@0.2.1': + resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==} + deprecated: 'Switch to "qr" (new package name) for security updates: npm install qr' + + '@phosphor-icons/webcomponents@2.1.5': + resolution: {integrity: sha512-JcvQkZxvcX2jK+QCclm8+e8HXqtdFW9xV4/kk2aL9Y3dJA2oQVt+pzbv1orkumz3rfx4K9mn9fDoMr1He1yr7Q==} + + '@protobuf-ts/grpcweb-transport@2.11.1': + resolution: {integrity: sha512-1W4utDdvOB+RHMFQ0soL4JdnxjXV+ddeGIUg08DvZrA8Ms6k5NN6GBFU2oHZdTOcJVpPrDJ02RJlqtaoCMNBtw==} + + '@protobuf-ts/runtime-rpc@2.11.1': + resolution: {integrity: sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ==} + + '@protobuf-ts/runtime@2.11.1': + resolution: {integrity: sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ==} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.1': + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.2': + resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} + + '@reown/appkit-common@1.8.11': + resolution: {integrity: sha512-rRcxrah6uouqEo/VbniVH11Y3H27BsP+Psv2+Usic+3Rt4kiSImIyeDG1YBV0gZNmME9N3sXHK8Bt7iqkxdOWw==} + + '@reown/appkit-controllers@1.8.11': + resolution: {integrity: sha512-V3hPB6NE7kM+7pS8n4ygZWbMh/XoHYxdPWxH3qtDlvYlH9Rgc3yvU8+IFWdB79Ta0lyJIbGqVlQeH5sQe4QOsw==} + + '@reown/appkit-pay@1.8.11': + resolution: {integrity: sha512-68IB3sKfxlCwLz44jvWWpULnmyIGHwnItojrr/PRXUof3z9t/nV8G7FiRY4ZDIo75EkabcIguhtYNSQ7R3vZbA==} + + '@reown/appkit-polyfills@1.8.11': + resolution: {integrity: sha512-pP9k5dvtWil88Zv3UgGurtbUmTx47z/5eriClGf8JI0VjBu/IExbAHg2gIZNEFdvkFD5/fIqIg8zno46SKbCKQ==} + + '@reown/appkit-scaffold-ui@1.8.11': + resolution: {integrity: sha512-oCEhNdUh2d59UHp/rLwfzv5odWg0pw000fg4Z53orjnKzcZfBpBDM00I9hu2pijnaYitJVqwsqCQ1F1q6hju/Q==} + + '@reown/appkit-ui@1.8.11': + resolution: {integrity: sha512-kBWZCiGaB/M2exIiDglsaTWYsWR0L89WXi7IFA6RgW0B0piYv5eiS3l/KPNj9/zxK8UnKsGsMefxl/UK/QqMng==} + + '@reown/appkit-utils@1.8.11': + resolution: {integrity: sha512-6Wplz7LNe2HoxHmGGYT6FIp8saa0DzVP/427jlNuWpkL65/azPyYjA8tKptxbFWViQ4VYBsqLoQxivXC/xNMBg==} + peerDependencies: + valtio: 2.1.7 + + '@reown/appkit-wallet@1.8.11': + resolution: {integrity: sha512-tCzrieMuOD4tDcNQjMe83T38tJUfRdv4LG+cYGyGK1RpPGaszbq06TQVbCPkRrGiTELwkrKwXjSg1XAuHktS2w==} + + '@reown/appkit@1.8.11': + resolution: {integrity: sha512-G96zt1P3ASrivV7HRrFQuzkCEzSmy3ca7cSQxaLeIS+P2VVhjE5YAyINArGVbooY0heHCPvQuTNM+YgK4oBmfg==} + '@rolldown/binding-android-arm-eabi@1.2.13': resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -802,6 +1622,128 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@simplewebauthn/browser@13.1.0': + resolution: {integrity: sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==} + + '@simplewebauthn/types@12.0.0': + resolution: {integrity: sha512-q6y8MkoV8V8jB4zzp18Uyj2I7oFp2/ONL8c3j8uT06AOWu3cIChc1au71QYHrP2b+xDapkGTiv+9lX7xkTlAsA==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@solana/buffer-layout-utils@0.2.0': + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.0.0-rc.1': + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-data-structures@2.0.0-rc.1': + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.0.0-rc.1': + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-strings@2.0.0-rc.1': + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + + '@solana/codecs@2.0.0-rc.1': + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.0.0-rc.1': + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + hasBin: true + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/options@2.0.0-rc.1': + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + + '@solana/spl-token-group@0.0.7': + resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token-metadata@0.1.6': + resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token@0.4.14': + resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.5 + + '@solana/wallet-standard-chains@1.1.2': + resolution: {integrity: sha512-EZobEGclDBAFplpJC5F3d/s8Xnlqc5isNKuPrd5o9ZPZ7tWN84O0e68yIZ8MAOj9V7ieRadNiHtql7uIXCTyXg==} + engines: {node: '>=22'} + + '@solana/wallet-standard-features@1.5.0': + resolution: {integrity: sha512-gxlLaEfPAqbhd3LNkK0Ks2pbVvDm1SDGqBK/ynDQy13Gu+qiURLpRCfSPjbtrw5bmqQsZ6rS2YJHL31bY/Koag==} + engines: {node: '>=22'} + + '@solana/web3.js@1.98.1': + resolution: {integrity: sha512-gRAq1YPbfSDAbmho4kY7P/8iLIjMWXAzBJdP9iENFR+dFQSBSueHzjK/ou8fxhqHP9j+J4Msl4p/oDemFcIjlg==} + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -838,33 +1780,121 @@ packages: '@swc/helpers@0.5.23': resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + + '@thumbmarkjs/thumbmarkjs@0.16.0': + resolution: {integrity: sha512-NKyqCvP6DZKlRf6aGfnKS6Kntn2gnuBxa/ztstjy+oo1t23EHzQ54shtli0yV5WAtygmK1tti/uL2C2p/kW3HQ==} + deprecated: Please upgrade to v1 + + '@turnkey/api-key-stamper@0.4.7': + resolution: {integrity: sha512-/0/kW7v+uCnmHnGMoHSXn4Vb/MxLAIivGxX/T0L4vVoIiJalQmqcCtgiWnPWZDiJNGjMKp+jd/8j6VXgbVVozg==} + engines: {node: '>=18.0.0'} + + '@turnkey/crypto@2.5.0': + resolution: {integrity: sha512-aeYPO9rPFlM6eG+hjDiE6BKi9O6xcSDSIoq3mlw6KaaDgg6T2wFVapquIhAvwdTn+SMemDhcw2XaK5jsrQvsdQ==} + engines: {node: '>=18.0.0'} + + '@turnkey/encoding@0.5.0': + resolution: {integrity: sha512-nRlKRQa6B5/xltGUKN1iKo4h4YC/0iFz0fAuFFZevc+YGDj7ddAP/3HkWmVvLmdoicUgs9rxvWbLRlgqPkbwzQ==} + engines: {node: '>=18.0.0'} + + '@turnkey/http@3.10.0': + resolution: {integrity: sha512-PSOZV6HzpH39Wt0tILMOUgdq3wZw1jmBcbEWHDJDelCYPCLO1X7XAGGmxZliQ5y8IKzlp3DCI/qkkxswmDlDlg==} + engines: {node: '>=18.0.0'} + + '@turnkey/iframe-stamper@2.5.0': + resolution: {integrity: sha512-XjntbA5CNjxGRH+loceAlVLL9PG9Q4Y7p5zjBm4DeKclhD6lpUl9h8INArMEXIFbfLwLjjS6Q+SmQG4BHvNY6A==} + engines: {node: '>=18.0.0'} + + '@turnkey/indexed-db-stamper@1.1.1': + resolution: {integrity: sha512-pKEMTCTg6Kn76nvYu3vq3HfsdkZ7BmO5MSrXqk7K2TJ4griL/oEzIhlSNAnihpohIRTmIkSCxOAgyIe43oB+Cg==} + engines: {node: '>=18.0.0'} + + '@turnkey/sdk-browser@5.8.0': + resolution: {integrity: sha512-FnpOur2fzsnGSxiAFl8fvCqoSsD7EvOV+fPvxFofxICYrb/S1K3DcTRz7BxGvi4tPWFbYHZVqquYKzGs+SHeFw==} + engines: {node: '>=18.0.0'} + + '@turnkey/sdk-server@4.7.0': + resolution: {integrity: sha512-xgDV5aTtBNPu/0eEx6d5CoW8klgvajXBdkROphFnMcZlVq8YutVJP7tgECpuvJTYe0Cc6zvKHNoNQCJZ082bYw==} + engines: {node: '>=18.0.0'} + + '@turnkey/sdk-types@0.3.0': + resolution: {integrity: sha512-w9WLK8rMBLMIQNtaEriW2mQRuRxWu5GCOZatReaB5FRrtUFJroXjB3V8C+wUER02w3znyZzklQGPL1P32n6iuA==} + engines: {node: '>=18.0.0'} + + '@turnkey/solana@1.0.42': + resolution: {integrity: sha512-+SxerY0mAfdoak61biZxr7D+izqnYLrhfCfXxHcHG1lp+cG1u22eyx4zcrjLbzwmUBQ30Iu32kLMTVu+/b5AzA==} + engines: {node: '>=18.0.0'} + + '@turnkey/viem@0.13.0': + resolution: {integrity: sha512-l0PngrJlCgRvnuahYxPOhTB0SfiIAMHpX8fZOC3f7hEa1g1p4sN2RUAAm5rHI0KCXuLf5j4YWRUI6p6q2QC8tw==} + engines: {node: '>=18.0.0'} + peerDependencies: + viem: ^1.16.6 || ^2.24.2 + + '@turnkey/wallet-stamper@1.0.8': + resolution: {integrity: sha512-MgXYt5/ROvnkwC/hZyMMqPcOmENuYDq+Efyf0ipCX09Q3NfM6TLJvR3AgJuVN6WrDO8GNcpQQTBdy8kbAXMlLQ==} + + '@turnkey/webauthn-stamper@0.5.1': + resolution: {integrity: sha512-eBwceTStSSettBQsLo3X5eJEarcK9f20cGUdi6jOesXOP86iYEIgR4+aH2qyCQ3eaovj+Hl44UGngXueIm/tKg==} + engines: {node: '>=18.0.0'} + '@tybys/wasm-util@0.10.4': resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/lodash@4.17.27': + resolution: {integrity: sha512-VenMRv/eKNrspX9v3H4dbmjsrnCOYdYBG3kxXKk3dG6X+urBGcj2Prww3xw1U5K4FV/mE4h5GbWd0szEKf+9ew==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@18.19.130': resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} '@types/node@24.19.0': resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==} + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/pg@8.23.1': resolution: {integrity: sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==} @@ -876,6 +1906,21 @@ packages: '@types/react@19.3.0': resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.18.2': + resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==} + '@typescript-eslint/eslint-plugin@8.71.1': resolution: {integrity: sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1088,93 +2133,316 @@ packages: '@vitest/utils@4.1.12': resolution: {integrity: sha512-Q3awXrwOfEV+qc3WmO5ONyE0yO7Q1gQ9/oyHxGLZ/pl7N3NO/ZztqQwKLuwMkV+CA1JYSIeO3gkHnRDIo4AVaA==} - '@workflow/serde@4.1.0': - resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + '@vue/reactivity@3.5.44': + resolution: {integrity: sha512-u+QJdKeBBEADkPdevsL+6E12QlYVfBD8Zcw5qjDQKtamI6l14KyqazJMobhCKelhWN5zpyKUiEDoTyHE93cqWw==} - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} + '@vue/shared@3.5.44': + resolution: {integrity: sha512-H82XLH0DjmSOdbEwO15x3QTo1f5PWEtv237eLpYKc0mqLu+B8hnq16lFWmuBmNurkeiG3wr+oM1FhOll/YVFRg==} - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@wallet-standard/app@1.0.1': + resolution: {integrity: sha512-LnLYq2Vy2guTZ8GQKKSXQK3+FRGPil75XEdkZqE6fiLixJhZJoJa5hT7lXxwe0ykVTt9LEThdTbOpT7KadS26Q==} + engines: {node: '>=16'} - acorn@8.19.0: - resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} - engines: {node: '>=0.4.0'} - hasBin: true + '@wallet-standard/app@1.1.1': + resolution: {integrity: sha512-WDGwoByhP5gwHH01r5EaLgQdLVkACPCdOMQhmhn8rsm10h/siSgTorShzBxrn0ExSPof+Lu+C3TfgqBrPa1xoQ==} + engines: {node: '>=22'} - agentkeepalive@4.6.0: - resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} - engines: {node: '>= 8.0.0'} + '@wallet-standard/base@1.0.1': + resolution: {integrity: sha512-1To3ekMfzhYxe0Yhkpri+Fedq0SYcfrOfJi3vbLjMwF2qiKPjTGLwZkf2C9ftdQmxES+hmxhBzTwF4KgcOwf8w==} + engines: {node: '>=16'} - ai@7.0.137: - resolution: {integrity: sha512-JxrPkSQknxIN/gYqS3UQksExS6eWI23QMPBrKMGXeeFHhru6xFtF4MuMq17WaHD+lXPh0lne6H0BM2Z2VMW9EQ==} + '@wallet-standard/base@1.1.1': + resolution: {integrity: sha512-gggIHTtxicF9XFMQ12DkfS6NAG92Ak795JeSA7f2whAQ6Y3AkMWWuCMxSZXG2NIPN42kEaZSNVjqMsJRaJRxMQ==} engines: {node: '>=22'} - peerDependencies: - zod: 4.6.7 - ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + '@wallet-standard/core@1.1.1': + resolution: {integrity: sha512-5Xmjc6+Oe0hcPfVc5n8F77NVLwx1JVAoCVgQpLyv/43/bhtIif+Gx3WUrDlaSDoM8i2kA2xd6YoFbHCxs+e0zA==} + engines: {node: '>=16'} - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + '@wallet-standard/errors@0.1.2': + resolution: {integrity: sha512-oEzKUqJefKby6wcIvaJgrSEe/uNn/rnqkJ0P/85K+h0i5Tdo9E3L22VWq/j5K1e8hHMnZd6LgaIr8m/Wn7X/Ng==} + engines: {node: '>=22'} + hasBin: true - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + '@wallet-standard/experimental-features@0.1.1': + resolution: {integrity: sha512-WKtnET1okeDACTbxmePGOGaIUrGvlu/DestLZvZ/ddFpUKw7nokkbinX/gHzsuAC9WGtLyhqLSppAHzN+vAAaQ==} + engines: {node: '>=16'} - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} + '@wallet-standard/features@1.0.3': + resolution: {integrity: sha512-m8475I6W5LTatTZuUz5JJNK42wFRgkJTB0I9tkruMwfqBF2UN2eomkYNVf9RbrsROelCRzSFmugqjKZBFaubsA==} + engines: {node: '>=16'} - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} + '@wallet-standard/features@1.1.1': + resolution: {integrity: sha512-aCWYmVeSCGViyEU5k7GMoW8zxE4Gs+C1s1Pp2XLesvSNlnZ4PMES9HUnTB3hl0b3RVj7C61yze3IWyrncqg4MA==} + engines: {node: '>=22'} - array-includes@3.2.0: - resolution: {integrity: sha512-VXY5eFRarnXcYxwBjJzPmEhH55+rmP79/+ueDhi0F+TuqfHCItagIHqxeUZrmgrOPa31QTh9H85DjX3FfJ0FTg==} - engines: {node: '>= 0.4'} + '@wallet-standard/wallet@1.1.0': + resolution: {integrity: sha512-Gt8TnSlDZpAl+RWOOAB/kuvC7RpcdWAlFbHNoi4gsXsfaWa1QCT6LBcfIYTPdOZC9OVZUDwqGuGAcqZejDmHjg==} + engines: {node: '>=16'} - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} + '@wallet-standard/wallet@1.1.1': + resolution: {integrity: sha512-8WiRPaKk/wNNRZhB2eVhpR/JW7/aqTCMoZhgVUCujuzDmxxmGvsosMxdCG4NAdYkoyozAHCX8/xLtlWUn5mNdQ==} + engines: {node: '>=22'} - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} + '@walletconnect/core@2.21.5': + resolution: {integrity: sha512-CxGbio1TdCkou/TYn8X6Ih1mUX3UtFTk+t618/cIrT3VX5IjQW09n9I/pVafr7bQbBtm9/ATr7ugUEMrLu5snA==} + engines: {node: '>=18'} - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} + '@walletconnect/core@2.22.4': + resolution: {integrity: sha512-ZQnyDDpqDPAk5lyLV19BRccQ3wwK3LmAwibuIv3X+44aT/dOs2kQGu9pla3iW2LgZ5qRMYvgvvfr5g3WlDGceQ==} + engines: {node: '>=18.20.8'} - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} + '@walletconnect/core@2.23.2': + resolution: {integrity: sha512-KkaTELRu8t/mt3J9doCQ1fBGCbYsCNfpo2JpKdCwKQR7PVjVKeVpYQK/blVkA5m6uLPpBtVRbOMKjnHW1m7JLw==} + engines: {node: '>=18.20.8'} - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} + '@walletconnect/ethereum-provider@2.23.2': + resolution: {integrity: sha512-/JQTTs3bPNatEjWr82p4EAstFAntL85grNhSmpdJxxpEvFcWHMqtrK+ozIy4jBiDZpuVasvL5yjcl5oPQC3r8Q==} - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} - ast-types-flow@0.0.8: - resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/logger@3.0.0': + resolution: {integrity: sha512-DDktPBFdmt5d7U3sbp4e3fQHNS1b6amsR8FmtOnt6L2SnV7VfcZr8VmAGL12zetAR+4fndegbREmX0P8Mw6eDg==} + + '@walletconnect/logger@3.0.2': + resolution: {integrity: sha512-7wR3wAwJTOmX4gbcUZcFMov8fjftY05+5cO/d4cpDD8wDzJ+cIlKdYOXaXfxHLSYeDazMXIsxMYjHYVDfkx+nA==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.21.5': + resolution: {integrity: sha512-IAs/IqmE1HVL9EsvqkNRU4NeAYe//h9NwqKi7ToKYZv4jhcC3BBemUD1r8iQJSTHMhO41EKn1G9/DiBln3ZiwQ==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/sign-client@2.22.4': + resolution: {integrity: sha512-la+sol0KL33Fyx5DRlupHREIv8wA6W33bRfuLAfLm8pINRTT06j9rz0IHIqJihiALebFxVZNYzJnF65PhV0q3g==} + + '@walletconnect/sign-client@2.23.2': + resolution: {integrity: sha512-LL5KgmJHvY5NqQn+ZHQJLia1p6fpUWXHtiG97S5rNfyuPx6gT/Jkkwqc2LwdmAjFkr61t8zTagHC9ETq203mNA==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.21.5': + resolution: {integrity: sha512-kpTXbenKeMdaz6mgMN/jKaHHbu6mdY3kyyrddzE/mthOd2KLACVrZr7hrTf+Fg2coPVen5d1KKyQjyECEdzOCw==} + + '@walletconnect/types@2.22.4': + resolution: {integrity: sha512-KJdiS9ezXzx1uASanldYaaenDwb42VOQ6Rj86H7FRwfYddhNnYnyEaDjDKOdToGRGcpt5Uzom6qYUOnrWEbp5g==} + + '@walletconnect/types@2.23.2': + resolution: {integrity: sha512-5dxBCdUM+4Dqe1/A7uqkm2tWPXce4UUGSr+ImfI0YjwEExQS8+TzdOlhMt3n32ncnBCllU5paG+fsndT06R0iw==} + + '@walletconnect/universal-provider@2.22.4': + resolution: {integrity: sha512-TF2RNX13qxa0rrBAhVDs5+C2G8CHX7L0PH5hF2uyQHdGyxZ3pFbXf8rxmeW1yKlB76FSbW80XXNrUes6eK/xHg==} + + '@walletconnect/universal-provider@2.23.2': + resolution: {integrity: sha512-vs9iorPUAiVesFJ95O6XvLjmRgF+B2TspxJNL90ZULbrkRw4JFsmaRdb965PZKc+s182k1MkS/MQ0o964xRcEw==} + + '@walletconnect/utils@2.21.5': + resolution: {integrity: sha512-RSPSxPvGMuvfGhd5au1cf9cmHB/KVVLFotJR9ltisjFABGtH2215U5oaVp+a7W18QX37aemejRkvacqOELVySA==} + + '@walletconnect/utils@2.22.4': + resolution: {integrity: sha512-coAPrNiTiD+snpiXQyXakMVeYcddqVqII7aLU39TeILdPoXeNPc2MAja+MF7cKNM/PA3tespljvvxck/oTm4+Q==} + + '@walletconnect/utils@2.23.2': + resolution: {integrity: sha512-ReSjU3kX+3i3tYJQZbVfetY5SSUL+iM6uiIVVD1PJalePa/5A40VgLVRTF7sDCJTIFfpf3Mt4bFjeaYuoxWtIw==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + '@workflow/serde@4.1.0': + resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.2.3: + resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} + peerDependencies: + typescript: '>=5.0.4' + zod: 4.6.7 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.3.0: + resolution: {integrity: sha512-fk6Te+bojIFrMvMZrnOO+SxCB+RUksTGOzq/60ZRvs1L+BVzvi2bqt9L3W/17ZLdZsyM1FuYf65P5nlmoiH1Bg==} + peerDependencies: + typescript: '>=5.0.4' + zod: 4.6.7 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + ably@2.17.1: + resolution: {integrity: sha512-70yfXHoM7JtJD/8FCtPD1gkWW0f+AJqbJp0PsqDAqiyxFB8cPFY+FuKHgNTYb8eRHKXq8hT1xiDphUcY0+GHnA==} + engines: {node: '>=16'} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + ai@7.0.137: + resolution: {integrity: sha512-JxrPkSQknxIN/gYqS3UQksExS6eWI23QMPBrKMGXeeFHhru6xFtF4MuMq17WaHD+lXPh0lne6H0BM2Z2VMW9EQ==} + engines: {node: '>=22'} + peerDependencies: + zod: 4.6.7 + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.2.0: + resolution: {integrity: sha512-VXY5eFRarnXcYxwBjJzPmEhH55+rmP79/+ueDhi0F+TuqfHCItagIHqxeUZrmgrOPa31QTh9H85DjX3FfJ0FTg==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -1183,10 +2451,17 @@ packages: resolution: {integrity: sha512-9WTZxEjsZ7b13TH8JPmbV2z8CHbl80/2hm3XPEG4JgNdQLK81IBRXmSxHfMAOkSqQeRxT/0dwNDz2GOm3zzpcQ==} engines: {node: '>=4'} + axios@1.20.0: + resolution: {integrity: sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1194,11 +2469,59 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + + base-x@4.0.1: + resolution: {integrity: sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + base32.js@0.1.0: + resolution: {integrity: sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==} + engines: {node: '>=0.12.0'} + + base64-js@1.0.2: + resolution: {integrity: sha512-ZXBDPMt/v/8fsIqn+Z5VwrhdR6jVka0bYobHdGia0Nxi7BJ9i/Uvml3AocHIBtIIBhZjBw5MR0aR4ROs/8+SNg==} + engines: {node: '>= 0.4'} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.11.27: resolution: {integrity: sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==} engines: {node: '>=6.0.0'} hasBin: true + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bn.js@5.2.5: + resolution: {integrity: sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==} + + bops@1.0.1: + resolution: {integrity: sha512-qCMBuZKP36tELrrgXpAfM+gHzqa0nLsWZ+L37ncsb8txYlnAoxOPpVp+g7fK0sGkMXfA0wl8uQkESqw3v4HNag==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + bowser@2.15.0: + resolution: {integrity: sha512-xic6KSZglg/I4ymp45fdM4GWfYpBK79Fxd/TOvJktlaPgQqqDxvmGwOPZl2V0dyeS3Lj5c180bLhXF43iyAjZQ==} + brace-expansion@1.1.21: resolution: {integrity: sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==} @@ -1215,6 +2538,33 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + bs58check@4.0.0: + resolution: {integrity: sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.1.0: + resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} + engines: {node: '>=6.14.2'} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1231,9 +2581,16 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + caniuse-lite@1.0.30001815: resolution: {integrity: sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==} + centrifuge@5.8.0: + resolution: {integrity: sha512-ENH1jz6VeRuGb3yHNhgB0V0SqRKX+iYdtM9Du/E59m484epjNPfsgJw4UbmOmjgSXGEita1UoOXlZ6Ba1ooT1g==} + chai@6.3.0: resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} engines: {node: '>=18'} @@ -1242,9 +2599,31 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1252,10 +2631,32 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1263,13 +2664,40 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + country-list@2.3.0: + resolution: {integrity: sha512-qZk66RlmQm7fQjMYWku1AyjlKPogjPEorAZJG88owPExoPV8EsyCcuFLvO2afTXHEhi9liVOoyd+5A6ZS5QwaA==} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + crossws@0.4.15: resolution: {integrity: sha512-NsUOpDZosz7nyI+qEIl05yaiXOWaXH2oTeM+XBWtiSWZtb5rzcIsl1AST/HzM2jzUn76eFuyrkn83E6iSBRUvw==} peerDependencies: @@ -1296,6 +2724,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + db0@0.4.1: resolution: {integrity: sha512-6RBY/bSn42UrqATwsiULj2uYFyEykB3XeA/NLIVQeHNXlYV6D4Idxx3/aa6k5Y45Dwzx7sygeLotnqHWSeURYA==} @@ -1316,9 +2747,29 @@ packages: supports-color: optional: true + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@2.2.1: + resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==} + engines: {node: '>=0.10.0'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -1327,32 +2778,77 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eciesjs@0.4.17: + resolution: {integrity: sha512-TOOURki4G7sD1wDCjj7NfLaXZZ49dFOeEb5y39IXpb8p0hRzVvfvzZHOi5JcT+PpyAbi/Y+lxPb8eTag2WYH8w==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + electron-to-chromium@1.5.451: resolution: {integrity: sha512-vUNKPrUzw8ByEMOxloq0a71iD/mPuPxVkbDm3G5YhnxTzOw/I6qAg2MUS0cYj/c267lWmw26yW4Vv7foxTxPLg==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + env-runner@0.2.3: resolution: {integrity: sha512-S8EFBKyznRwPVwayK187cYjvnpgC92xy+q0BIF++V965pfjMVVRbQ/HoTYGA/1EHmZ7E68k6Heq+4WnvVhOL5w==} hasBin: true + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + es-abstract-get@1.0.0: resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==} engines: {node: '>= 0.4'} @@ -1392,6 +2888,15 @@ packages: resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} + es-toolkit@1.39.3: + resolution: {integrity: sha512-Qb/TCFCldgOy8lZ5uC7nLGdqJwSabkQiYQShmw4jyiPk1pZzaYWTwaYKYP7EgLccWYgZocMrtItrwh683voaww==} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + esbuild@0.28.2: resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} engines: {node: '>=18'} @@ -1529,6 +3034,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + eve@0.79.1: resolution: {integrity: sha512-7hbpSi6mCqsrq3W7C9Y8Z2vTny01hunaNilEFj2qy/DkotztaW+KD4BNwut3oz2iSQ8yryyl46XhOspQ6PmZOg==} engines: {node: '>=24'} @@ -1559,6 +3067,13 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + eventsource-parser@3.1.1: resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==} engines: {node: '>=18.0.0'} @@ -1567,9 +3082,16 @@ packages: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} + exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + exsolve@1.1.3: resolution: {integrity: sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==} + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1583,6 +3105,19 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + fastq@1.20.3: resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==} @@ -1599,10 +3134,24 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1614,7 +3163,20 @@ packages: flatted@3.4.4: resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} - for-each@0.3.5: + focus-lock@1.3.6: + resolution: {integrity: sha512-Ik/6OCk9RQQ0T5Xw+hKNLWrjSMtv51dD4GRmJjbD5a58TIEpI5a5iXagKVl3Z5UuyslMCA8Xwnu76jQob62Yhg==} + engines: {node: '>=10'} + + follow-redirects@1.16.2: + resolution: {integrity: sha512-/kVP2U8z596Ia0gwFrwyIeo74ta5aVmSeU1FfAUMAmcEP5EP7zydmag3SLiN64NaRKef3lxsq7i/g7ltJQDGow==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -1629,6 +3191,14 @@ packages: resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} engines: {node: '>= 12.20'} + formik@2.2.9: + resolution: {integrity: sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA==} + peerDependencies: + react: '>=16.8.0' + + fp-ts@2.16.11: + resolution: {integrity: sha512-LaI+KaX2NFkfn1ZGHoKCmcfv7yrZsC3b8NtWsTVQeHkq4F27vI5igUuO53sxqDEa2gNQMHFPmpojDw/1zmUK7w==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1652,6 +3222,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -1660,6 +3234,10 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -1691,6 +3269,23 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + + gql.tada@1.11.4: + resolution: {integrity: sha512-UQnhJUhSM0MV8cpcgjci/7ET8LnmHx9o9FtZqU4sH+ILiBVG5rnfXJzNdzTN+Y7MuCz6Pp3XE/VPEVqmO969jw==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + graphql@16.14.2: + resolution: {integrity: sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + h3@2.0.2: resolution: {integrity: sha512-+/zvHSNldYpNURuUUG+y1KzdASUhNnSd1VpqxYFVY40ov3YzuBnCETaUQaT+QbKkoxhh9LRa6AEQdB14LALwdA==} engines: {node: '>=20.19.0'} @@ -1737,15 +3332,48 @@ packages: hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hookable@6.1.2: resolution: {integrity: sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==} + hpke-js@1.8.0: + resolution: {integrity: sha512-N0PFQlUQsIPS9++nUNn2ZsxTPSv8pONyyrXIGZl0iiherRfS0XW1SvTd+RmepD0TN1S9zzTJkEutMIWWYt0/4w==} + engines: {node: '>=16.0.0'} + + html-parse-stringify@3.1.0: + resolution: {integrity: sha512-E0oAXcELOtsXe+BmpJ2EZyedbldPpriV5vICzEuo6xjC/D1lDukOI7KrpfQGF2Qc4wWEy0nk3bFORS2K5ZAhFQ==} + + http-cache-semantics@4.3.0: + resolution: {integrity: sha512-M5t5LlJpS1UHMjvwRQVdFHvPISGeLAxNcrWuJkeGh0KxsqCHZ1O3NXZU/8x7cD0BDcGW8kapxMKTvwlqrNkHkA==} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + httpxy@0.5.5: resolution: {integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==} humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + i18next@23.4.6: + resolution: {integrity: sha512-jBE8bui969Ygv7TVYp0pwDZB7+he0qsU+nz7EcfdqSh+QvKjEfl9YPRQd/KrGiMhTYFGkeuPaeITenKK/bSFDg==} + + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + + idb-keyval@6.3.0: + resolution: {integrity: sha512-um+2dgAWmYsu615EXpWVwSmapJhON0G43t3Ka/EVaohzPQXSMqKEqeDK/oIW3Ow+BXaF2PvSc+oBTFp793A5Ow==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1762,14 +3390,41 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + input-otp@1.4.2: + resolution: {integrity: sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + io-ts@2.2.22: + resolution: {integrity: sha512-FHCCztTkHoV9mdBsHpocLpdTAfh956ZQcIkWQxxS0U5HT53vtrcuYdQneEJKH6xILaLNzXVl2Cvwtoy8XNN0AA==} + peerDependencies: + fp-ts: ^2.5.0 + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + is-async-function@2.1.1: resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} @@ -1813,6 +3468,10 @@ packages: resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-generator-function@1.1.2: resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} @@ -1879,10 +3538,25 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + jayson@4.3.0: + resolution: {integrity: sha512-AauzHcUcqs8OBnCHOkJY280VaTiCm57AbuO7lqzcw7JapGj50BisE3xhksye4zlTSR1+1tAz67wLTl8tEH1obQ==} + engines: {node: '>=8'} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1898,6 +3572,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -1907,6 +3584,9 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -1920,9 +3600,16 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -2008,17 +3695,57 @@ packages: resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lit-element@4.2.2: + resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} + + lit-html@3.3.3: + resolution: {integrity: sha512-el8M6jK2o3RXBnrSHX3ZKrsN8zEV63pSExTO1wYJz7QndGYZ8353e2a5PPX+qHe2aGayfnchQmkAojaWAREOIA==} + + lit@3.3.0: + resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2033,6 +3760,9 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -2050,6 +3780,14 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@10.2.6: resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} @@ -2063,6 +3801,12 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + nanoclone@0.2.1: + resolution: {integrity: sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==} + nanoid@3.3.20: resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2114,6 +3858,9 @@ packages: resolution: {integrity: sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==} engines: {node: '>= 0.4'} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -2123,10 +3870,25 @@ packages: encoding: optional: true + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.5: + resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==} + node-releases@2.0.57: resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==} engines: {node: '>=18'} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2166,6 +3928,25 @@ packages: ocache@0.3.0: resolution: {integrity: sha512-RS/9P0zeBb0gDJmadGERLH8lZNXK7xbufTDhclkXGvFGTsj0G4M5/cLk+mizcERH29mLXNnocfB5wjcK70wGJg==} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2174,18 +3955,81 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} + ox@0.12.4: + resolution: {integrity: sha512-+P+C7QzuwPV8lu79dOwjBKfB2CbnbEXe/hfyyrff1drrO1nOOj3Hc87svHfcW1yneRr3WXaKr6nz11nq+/DF9Q==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.14.56: + resolution: {integrity: sha512-Feinlj+deWEam6RIwurRE+eHZ2N3hoUb3AAjQ10BmxRCYIymfqNkv0eZ+4ln4GkgDmSGLD2rGtTMqsFYSVDC6w==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.7.1: + resolution: {integrity: sha512-+k9fY9PRNuAMHRFIUbiK9Nt5seYHHzSQs9Bj+iMETcGtlpS7SmBzcGSVUQO3+nqGLEiNK4598pHNFlVRaZbRsg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.3: + resolution: {integrity: sha512-KzyJP+fPV4uhuuqrTZyok4DC7vFzi7HLUFiUNEmpbyh59htKWkOC98IONC1zgXJPbHAhQgqs6B0Z6StCGhmQvg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + pako@2.2.0: + resolution: {integrity: sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2197,6 +4041,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -2245,11 +4093,42 @@ packages: resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@10.0.0: + resolution: {integrity: sha512-eI9pKwWEix40kfvSzqEP6ldqOoBIN7dwD/o91TY5z8vQI12sAffpR/pOqAD1IVVwIVHDpHjkq0joBPdJD0rafA==} + hasBin: true + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + playwright-core@1.62.1: resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==} engines: {node: '>=20'} hasBin: true + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + pony-cause@2.1.11: + resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} + engines: {node: '>=12.0.0'} + + poseidon-lite@0.2.1: + resolution: {integrity: sha512-xIr+G6HeYfOhCuswdqcFpSX47SPhm0EpisWJ6h7fHlWwaVIvH3dLnejpatrtw6Xc6HaLrpq05y7VRfvDmDGIog==} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -2278,32 +4157,162 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + + preact@10.29.8: + resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==} + peerDependencies: + preact-render-to-string: '>=5' + peerDependenciesMeta: + preact-render-to-string: + optional: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process-warning@5.1.1: + resolution: {integrity: sha512-oCkNVj4OKnKEcocVBcDfiIugN1/cE6rgfT3nCtzeqZPA8+rIxMaQ0xXzIkGP8Gj2qUaP1UR7uhJ1VD8lUCpzCg==} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + + protobufjs@7.6.6: + resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==} + engines: {node: '>=12.0.0'} + + proxy-compare@3.0.1: + resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode@1.3.2: + resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qr-code-styling@1.9.2: + resolution: {integrity: sha512-RgJaZJ1/RrXJ6N0j7a+pdw3zMBmzZU4VN2dtAZf8ZggCfRB5stEQ3IoDNGaNhYY3nnZKYlYSLl5YkfWN5dPutg==} + engines: {node: '>=18.18.0'} + + qrcode-generator@1.5.2: + resolution: {integrity: sha512-pItrW0Z9HnDBnFmgiNrY1uxRdri32Uh9EjNYLPVC2zZ3ZRIIEqBoDgm4DkvDwNNDHTK7FNkmr8zAa77BYc9xNw==} + + qrcode@1.5.1: + resolution: {integrity: sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + + querystring@0.2.0: + resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} + engines: {node: '>=0.4.x'} + deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + react-clientside-effect@1.2.8: + resolution: {integrity: sha512-ma2FePH0z3px2+WOu6h+YycZcEvFmmxIlAb62cF52bG86eMySciO/EQZeQMXd07kPCYB0a1dWDT5J+KE9mCDUw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom@19.3.0: resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==} peerDependencies: react: ^19.3.0 + react-fast-compare@2.0.4: + resolution: {integrity: sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==} + + react-focus-lock@2.13.6: + resolution: {integrity: sha512-ehylFFWyYtBKXjAO9+3v8d0i+cnc1trGS0vlTGhzFW1vbFXVUTmR8s2tt/ZQG8x5hElg6rhENlLG1H3EZK0Llg==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-i18next@13.5.0: + resolution: {integrity: sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==} + peerDependencies: + i18next: '>= 23.2.3' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + + react-international-phone@4.5.0: + resolution: {integrity: sha512-wjwHv+VfiwM49B5/6El4Z5vZKmf3ILpUeiOCI9X+b0Dq4g5nL8gROcwCdVcTXywxznbDSoxSassBX3i9tPZX6g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + react@19.3.0: resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==} engines: {node: '>=0.10.0'} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -2312,6 +4321,16 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2319,11 +4338,19 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.13: + resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==} + engines: {node: '>= 0.4'} + hasBin: true + resolve@2.0.0-next.7: resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==} engines: {node: '>= 0.4'} hasBin: true + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2340,6 +4367,9 @@ packages: resolution: {integrity: sha512-ySeaQkSrua+ut9g+65I7FHqOFBaY8tV0FmccXItoq0q21se32Q3u4YiW7/RqXSosWgYJaaKwRHXy3BST9PeCNQ==} engines: {node: '>=20.19.0'} + rpc-websockets@9.3.9: + resolution: {integrity: sha512-2iQDaTB4g5fDB2ihrTFSJSibCEuxaRi1q7qTW7ZO9/M5/TC+ToHA4D9/ffNLEbAoHNNrcdeP05oATNk44SKZXA==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2347,6 +4377,9 @@ packages: resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} engines: {node: '>=0.4'} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -2355,6 +4388,10 @@ packages: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + scheduler@0.28.0: resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} @@ -2362,11 +4399,19 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + semver@7.8.5: resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2379,6 +4424,13 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} + sha256-uint8array@0.10.7: + resolution: {integrity: sha512-1Q6JQU4tX9NqsDGodej6pkrUVQVNapLZnvkwIhddH/JqzBZF1fSaxSWNY6sziXBE8aEa2twtGkXUrwzGeZCMpQ==} + + sharp@0.35.0: + resolution: {integrity: sha512-BqvG5XbwPZ4NV0DK90d86leEECMsoa8bO0nqnKWlBDYxri4GJ7c4EDInaF6q20lTh/mATmnDIKWJFfXnoVfH5g==} + engines: {node: '>=20.9.0'} + sharp@0.35.5: resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==} engines: {node: '>=20.9.0'} @@ -2415,10 +4467,30 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + slow-redact@0.3.2: + resolution: {integrity: sha512-MseHyi2+E/hBRqdOi5COy6wZ7j7DxXRz9NkseavNYSvvWC06D8a5cidVZX3tcG5eCW3NIyVU4zT63hw0Q486jw==} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + sonic-boom@4.2.1: + resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} + source-map-js@1.2.2: resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} engines: {node: '>=0.10.0'} + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -2441,6 +4513,23 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -2464,6 +4553,13 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -2485,6 +4581,13 @@ packages: babel-plugin-macros: optional: true + stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2493,6 +4596,22 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + text-encoding@0.7.0: + resolution: {integrity: sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==} + deprecated: no longer maintained + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + thread-stream@3.2.0: + resolution: {integrity: sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2508,10 +4627,23 @@ packages: resolution: {integrity: sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==} engines: {node: '>=14.0.0'} + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.0.16: + resolution: {integrity: sha512-TkEq38COU640mzOKPk4D1oH3FFVvwEtMaKIfw/+F/umVsy7ONWu8PPQH0c11qJ/Jq/zbcQGprXGsT8GcaDSmJg==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + to-utf8@0.0.1: + resolution: {integrity: sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==} + + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2524,9 +4656,18 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -2559,10 +4700,23 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + + ulid@2.4.0: + resolution: {integrity: sha512-fIRiVTJNcSRmXKPZtGzFQv9WRrZ3M9eoptl/teFJvjOzmpU+/K/JH6HZ8deBfb5vMEpicJcLn7JmvdknlMq7Zg==} + hasBin: true + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -2583,6 +4737,68 @@ packages: unrs-resolver@1.12.2: resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} + unstorage@1.17.6: + resolution: {integrity: sha512-gjKtcmn/KwZuJZO9o2sc0esAQnhmTw0LviDHwevTXbJMYs0dRTp8ZEEWXHU0vTpzbN3cA0yxlTeyXssMp3zDqw==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + unstorage@2.0.0-alpha.11: resolution: {integrity: sha512-4rDO/NjgnkbVvWAPpxugX7YI/xVpC74NLrmAbH6I0D4hcSVq/1m5q2pSfQjP/ABs+7EsRtP/ZjyYMD9bEBgeTw==} @@ -2595,6 +4811,105 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url@0.11.0: + resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + utf-8-validate@6.0.6: + resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@11.1.1: + resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} + hasBin: true + + uuid@14.0.3: + resolution: {integrity: sha512-Sc5u1VVln93y1Xnz4R+CunOZc7R9LUcTmhj7Rc7Eg3HVcf7rVn2FOoa812fe0W8p3jD7xeoGSYbfqCGGH2B6xw==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + + valibot@1.5.0: + resolution: {integrity: sha512-nil6AkP2TChWL43Z5uJ6GTxX01CUA+g8LWUM+N/rB9NBbkUMaUsi9PUNzlUPgoKASgmx9f7eGOYpJ04/fSa6FQ==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + valtio@2.1.7: + resolution: {integrity: sha512-DwJhCDpujuQuKdJ2H84VbTjEJJteaSmqsuUltsfbfdbotVfNeTE4K/qc/Wi57I9x8/2ed4JNdjEna7O6PfavRg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + react: '>=18.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + viem@2.31.0: + resolution: {integrity: sha512-U7OMQ6yqK+bRbEIarf2vqxL7unSEQvNxvML/1zG7suAmKuJmipqdVTVJGKBCJiYsm/EremyO2FS4dHIPpGv+eA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.46.3: + resolution: {integrity: sha512-2LJS+Hyh2sYjHXQtzfv1kU9pZx9dxFzvoU/ZKIcn0FNtOU0HQuIICuYdWtUDFHaGXbAdVo8J1eCvmjkL9JVGwg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.57.7: + resolution: {integrity: sha512-x3UqqrcQuESaRVK6a0BvNmoNP0SVhu913uxEAxYLJx1lNYnj6ylTntfUdakCUKjk1+T+63gkdwFGJQ2O5C/nRw==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + vite@8.3.3: resolution: {integrity: sha512-cTAldKPImjg6c+gk48U19POPn3GCBzZwpdsN8ZMEEcbpes+6/wvfqUd0C2y3qYY4wsj8PwgFwrZ/1jBPVttMSg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2679,6 +4994,10 @@ packages: jsdom: optional: true + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} @@ -2701,6 +5020,9 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which-typed-array@1.1.24: resolution: {integrity: sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==} engines: {node: '>= 0.4'} @@ -2719,34 +5041,157 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.13: + resolution: {integrity: sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.22.0: + resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + engines: {node: '>= 6'} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yup@0.32.11: + resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} + engines: {node: '>=10'} + zod-validation-error@4.0.2: resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} engines: {node: '>=18.0.0'} peerDependencies: zod: 4.6.7 + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@4.6.7: resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} + zustand@5.0.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: + '@0no-co/graphql.web@1.3.4(graphql@16.14.2)': + optionalDependencies: + graphql: 16.14.2 + + '@0no-co/graphqlsp@1.18.0(graphql@16.14.2)(typescript@6.0.3)': + dependencies: + '@gql.tada/internal': 1.2.2(graphql@16.14.2)(typescript@6.0.3) + graphql: 16.14.2 + typescript: 6.0.3 + '@1password/sdk-core@0.5.0': {} '@1password/sdk@0.5.0': dependencies: '@1password/sdk-core': 0.5.0 + '@ably/msgpack-js@0.4.1': + dependencies: + bops: 1.0.1 + + '@adraffy/ens-normalize@1.11.1': {} + '@ai-sdk/gateway@4.0.110(zod@4.6.7)': dependencies: '@ai-sdk/provider': 4.0.26 @@ -2863,6 +5308,8 @@ snapshots: dependencies: '@babel/types': 7.29.8 + '@babel/runtime@7.29.10': {} + '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -2886,6 +5333,28 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@base-org/account@1.1.1(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@6.0.3)(zod@3.22.4) + preact: 10.24.2 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + zustand: 5.0.3(@types/react@19.3.0)(react@19.3.0) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@basis-theory/web-agentic@1.2.2': {} + '@browserbasehq/sdk@2.18.0': dependencies: '@types/node': 18.19.130 @@ -2907,89 +5376,1189 @@ snapshots: transitivePeerDependencies: - encoding - '@emnapi/core@1.10.0': + '@coinbase/wallet-sdk@4.3.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - optional: true + '@noble/hashes': 1.8.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + preact: 10.29.8 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - bufferutil + - preact-render-to-string + - typescript + - utf-8-validate + - zod + + '@crossmint/client-sdk-auth@1.3.31': + dependencies: + '@crossmint/client-sdk-base': 4.6.1 + '@crossmint/common-sdk-auth': 1.1.29 + '@crossmint/common-sdk-base': 0.13.0 + jwt-decode: 4.0.0 + transitivePeerDependencies: + - '@datadog/browser-rum' - '@emnapi/runtime@1.10.0': + '@crossmint/client-sdk-base@4.6.1': dependencies: - tslib: 2.8.1 - optional: true + '@crossmint/client-sdk-window': 1.2.0 + '@crossmint/common-sdk-base': 0.13.0 + '@datadog/browser-logs': 6.24.1 + exponential-backoff: 3.1.1 + uuid: 11.1.1 + zod: 3.22.4 + transitivePeerDependencies: + - '@datadog/browser-rum' + + '@crossmint/client-sdk-react-base@2.4.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@crossmint/client-sdk-auth': 1.3.31 + '@crossmint/client-sdk-base': 4.6.1 + '@crossmint/client-sdk-window': 1.2.0 + '@crossmint/client-signers': 0.3.1 + '@crossmint/common-sdk-auth': 1.1.29 + '@crossmint/common-sdk-base': 0.13.0 + '@crossmint/wallets-sdk': 1.20.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + react: 19.3.0 + transitivePeerDependencies: + - '@datadog/browser-rum' + - '@solana/web3.js' + - bufferutil + - typescript + - utf-8-validate + - zod + + '@crossmint/client-sdk-react-ui@4.12.1(@dynamic-labs-wallet/primitives@1.1.33)(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@basis-theory/web-agentic': 1.2.2 + '@crossmint/client-sdk-base': 4.6.1 + '@crossmint/client-sdk-react-base': 2.4.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@crossmint/client-sdk-window': 1.2.0 + '@crossmint/client-signers': 0.3.1 + '@crossmint/common-sdk-auth': 1.1.29 + '@crossmint/common-sdk-base': 0.13.0 + '@crossmint/wallets-sdk': 1.20.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs/ethereum': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@4.6.7) + '@dynamic-labs/sdk-react-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/solana': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4) + '@dynamic-labs/sui': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@emotion/react': 11.14.0(@types/react@19.3.0)(react@19.3.0) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0))(@types/react@19.3.0)(react@19.3.0) + '@mysten/sui': 1.45.2(typescript@6.0.3) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + bs58: 5.0.0 + clsx: 2.1.1 + color: 4.2.3 + input-otp: 1.4.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + lodash.isequal: 4.5.0 + ox: 0.6.9(typescript@6.0.3)(zod@3.22.4) + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + react-transition-group: 4.4.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + zod: 3.22.4 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@datadog/browser-rum' + - '@deno/kv' + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - preact-render-to-string + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate - '@emnapi/runtime@1.11.3': + '@crossmint/client-sdk-window@1.2.0': dependencies: - tslib: 2.8.1 - optional: true + zod: 3.22.4 - '@emnapi/wasi-threads@1.2.1': + '@crossmint/client-signers-cryptography@0.0.5': dependencies: - tslib: 2.8.1 - optional: true + '@noble/ciphers': 1.3.0 + bs58: 6.0.0 + zod: 3.22.4 - '@esbuild/aix-ppc64@0.28.2': - optional: true + '@crossmint/client-signers@0.3.1': + dependencies: + zod: 3.22.4 - '@esbuild/android-arm64@0.28.2': - optional: true + '@crossmint/common-sdk-auth@1.1.29': + dependencies: + '@crossmint/client-sdk-base': 4.6.1 + '@crossmint/common-sdk-base': 0.13.0 + transitivePeerDependencies: + - '@datadog/browser-rum' + + '@crossmint/common-sdk-base@0.13.0': + dependencies: + '@noble/hashes': 1.8.0 + bs58: 5.0.0 + + '@crossmint/wallets-sdk@1.20.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@crossmint/client-sdk-window': 1.2.0 + '@crossmint/client-signers': 0.3.1 + '@crossmint/client-signers-cryptography': 0.0.5 + '@crossmint/common-sdk-auth': 1.1.29 + '@crossmint/common-sdk-base': 0.13.0 + '@hey-api/client-fetch': 0.8.1 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + abitype: 1.0.8(typescript@6.0.3)(zod@3.22.4) + base32.js: 0.1.0 + bs58: 5.0.0 + ox: 0.6.9(typescript@6.0.3)(zod@3.22.4) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + transitivePeerDependencies: + - '@datadog/browser-rum' + - bufferutil + - typescript + - utf-8-validate + - zod - '@esbuild/android-arm@0.28.2': - optional: true + '@datadog/browser-core@6.24.1': {} - '@esbuild/android-x64@0.28.2': - optional: true + '@datadog/browser-logs@6.24.1': + dependencies: + '@datadog/browser-core': 6.24.1 - '@esbuild/darwin-arm64@0.28.2': - optional: true + '@dynamic-labs-connectors/base-account-evm@4.7.1(@dynamic-labs/ethereum-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)))(@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs/ethereum-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@dynamic-labs-connectors/metamask-evm@4.7.1(@dynamic-labs/ethereum-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)))(@dynamic-labs/ethereum@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4))(@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))': + dependencies: + '@dynamic-labs/ethereum': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@4.6.7) + '@dynamic-labs/ethereum-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@metamask/connect-evm': 2.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@metamask/connect-multichain': 1.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - bufferutil + - encoding + - supports-color + - utf-8-validate - '@esbuild/darwin-x64@0.28.2': - optional: true + '@dynamic-labs-connectors/metamask-solana@4.7.1(@dynamic-labs/solana-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6))(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs/solana-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@metamask/connect-solana': 2.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + bs58: 6.0.0 + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - bufferutil + - encoding + - supports-color + - utf-8-validate - '@esbuild/freebsd-arm64@0.28.2': - optional: true + '@dynamic-labs-sdk/assert-package-version@1.39.1': {} - '@esbuild/freebsd-x64@0.28.2': - optional: true + '@dynamic-labs-sdk/client@1.39.1(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs-sdk/assert-package-version': 1.39.1 + '@dynamic-labs-wallet/browser-wallet-client': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs/sdk-api-core': 0.92.0 + '@simplewebauthn/browser': 13.1.0 + ably: 2.17.1(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + buffer: 6.0.3 + eventemitter3: 5.0.1 + zod: 4.6.7 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - bufferutil + - debug + - react + - react-dom + - supports-color + - utf-8-validate - '@esbuild/linux-arm64@0.28.2': - optional: true + '@dynamic-labs-wallet/browser-wallet-client@1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@dynamic-labs-wallet/core': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs/logger': 5.13.0 + '@dynamic-labs/message-transport': 5.13.0 + transitivePeerDependencies: + - '@dynamic-labs-wallet/forward-mpc-client' + - debug + - supports-color - '@esbuild/linux-arm@0.28.2': - optional: true + '@dynamic-labs-wallet/core@1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs-wallet/primitives': 1.1.33 + '@dynamic-labs/sdk-api-core': 0.50.0 + axios: 1.20.0 + uuid: 11.1.0 + transitivePeerDependencies: + - debug + - supports-color - '@esbuild/linux-ia32@0.28.2': - optional: true + '@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs-wallet/forward-mpc-shared': 0.7.2(@dynamic-labs-wallet/primitives@1.1.33) + '@dynamic-labs-wallet/primitives': 1.1.33 + '@evervault/wasm-attestation-bindings': 0.3.1 + '@noble/hashes': 2.4.0 + eventemitter3: 5.0.1 + fp-ts: 2.16.11 + isows: 1.0.7(ws@8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate - '@esbuild/linux-loong64@0.28.2': - optional: true + '@dynamic-labs-wallet/forward-mpc-shared@0.7.2(@dynamic-labs-wallet/primitives@1.1.33)': + dependencies: + '@dynamic-labs-wallet/primitives': 1.1.33 + '@noble/ciphers': 0.4.1 + '@noble/hashes': 2.4.0 + '@noble/post-quantum': 0.5.4 + fp-ts: 2.16.11 + io-ts: 2.2.22(fp-ts@2.16.11) - '@esbuild/linux-mips64el@0.28.2': - optional: true + '@dynamic-labs-wallet/primitives@1.1.33': {} - '@esbuild/linux-ppc64@0.28.2': - optional: true + '@dynamic-labs/assert-package-version@4.100.5': + dependencies: + '@dynamic-labs/logger': 4.100.5 - '@esbuild/linux-riscv64@0.28.2': - optional: true + '@dynamic-labs/assert-package-version@5.13.0': + dependencies: + '@dynamic-labs/logger': 5.13.0 - '@esbuild/linux-s390x@0.28.2': - optional: true + '@dynamic-labs/embedded-wallet-evm@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/embedded-wallet': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/ethereum-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/webauthn': 4.100.5 + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/iframe-stamper': 2.5.0 + '@turnkey/viem': 0.13.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4) + '@turnkey/webauthn-stamper': 0.5.1 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - zod + + '@dynamic-labs/embedded-wallet-solana@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@dynamic-labs-sdk/client': 1.39.1(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/embedded-wallet': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/solana-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/webauthn': 4.100.5 + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@turnkey/iframe-stamper': 2.5.0 + '@turnkey/solana': 1.0.42(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@turnkey/webauthn-stamper': 0.5.1 + viem: 2.46.3(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - zod + + '@dynamic-labs/embedded-wallet@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/webauthn': 4.100.5 + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/http': 3.10.0 + '@turnkey/iframe-stamper': 2.5.0 + '@turnkey/webauthn-stamper': 0.5.1 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - utf-8-validate + + '@dynamic-labs/ethereum-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - utf-8-validate + + '@dynamic-labs/ethereum-gasless-core@4.100.5(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + + '@dynamic-labs/ethereum@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@4.6.7)': + dependencies: + '@coinbase/wallet-sdk': 4.3.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs-connectors/base-account-evm': 4.7.1(@dynamic-labs/ethereum-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)))(@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6))(@types/react@19.3.0)(bufferutil@4.1.0)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4) + '@dynamic-labs-connectors/metamask-evm': 4.7.1(@dynamic-labs/ethereum-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)))(@dynamic-labs/ethereum@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4))(@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/embedded-wallet-evm': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4) + '@dynamic-labs/ethereum-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/waas-evm': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@walletconnect/ethereum-provider': 2.23.2(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + buffer: 6.0.3 + eventemitter3: 5.0.1 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - preact-render-to-string + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod - '@esbuild/linux-x64@0.28.2': - optional: true + '@dynamic-labs/iconic@4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + sharp: 0.35.0 + url: 0.11.0 - '@esbuild/netbsd-arm64@0.28.2': - optional: true + '@dynamic-labs/locale@4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + i18next: 23.4.6 + react-i18next: 13.5.0(i18next@23.4.6)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + transitivePeerDependencies: + - react + - react-dom + - react-native - '@esbuild/netbsd-x64@0.28.2': - optional: true + '@dynamic-labs/logger@4.100.5': + dependencies: + eventemitter3: 5.0.1 - '@esbuild/openbsd-arm64@0.28.2': - optional: true + '@dynamic-labs/logger@5.13.0': + dependencies: + '@dynamic-labs/redaction': 1.1.0 + eventemitter3: 5.0.1 - '@esbuild/openbsd-x64@0.28.2': - optional: true + '@dynamic-labs/message-transport@5.13.0': + dependencies: + '@dynamic-labs/assert-package-version': 5.13.0 + '@dynamic-labs/logger': 5.13.0 + '@dynamic-labs/utils': 5.13.0 + '@vue/reactivity': 3.5.44 + eventemitter3: 5.0.1 + + '@dynamic-labs/multi-wallet@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + tslib: 2.4.1 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - utf-8-validate + + '@dynamic-labs/redaction@1.1.0': {} + + '@dynamic-labs/rpc-providers@4.100.5': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/types': 4.100.5 + + '@dynamic-labs/sdk-api-core@0.136.0': {} + + '@dynamic-labs/sdk-api-core@0.50.0': {} + + '@dynamic-labs/sdk-api-core@0.92.0': {} + + '@dynamic-labs/sdk-react-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(@types/react@19.3.0)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs-sdk/client': 1.39.1(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs-wallet/browser-wallet-client': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/iconic': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/locale': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/multi-wallet': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/store': 4.100.5 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@hcaptcha/react-hcaptcha': 1.4.4(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@marsidev/react-turnstile': 1.5.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@thumbmarkjs/thumbmarkjs': 0.16.0 + bs58: 5.0.0 + country-list: 2.3.0 + eventemitter3: 5.0.1 + formik: 2.2.9(react@19.3.0) + i18next: 23.4.6 + qrcode: 1.5.1 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + react-focus-lock: 2.13.6(@types/react@19.3.0)(react@19.3.0) + react-i18next: 13.5.0(i18next@23.4.6)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + react-international-phone: 4.5.0(react@19.3.0) + yup: 0.32.11 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - '@types/react' + - bufferutil + - debug + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - utf-8-validate + + '@dynamic-labs/solana-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + eventemitter3: 5.0.1 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + + '@dynamic-labs/solana@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(db0@0.4.1)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4)': + dependencies: + '@dynamic-labs-connectors/metamask-solana': 4.7.1(@dynamic-labs/solana-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6))(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/embedded-wallet-solana': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/solana-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/waas-svm': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4) + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connect': 4.100.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@wallet-standard/app': 1.0.1 + '@wallet-standard/base': 1.0.1 + '@wallet-standard/experimental-features': 0.1.1 + '@wallet-standard/features': 1.0.3 + '@walletconnect/sign-client': 2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/types': 2.21.5(db0@0.4.1) + '@walletconnect/utils': 2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + bs58: 5.0.0 + eventemitter3: 5.0.1 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - debug + - encoding + - fastestsmallesttextencoderdecoder + - ioredis + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - uploadthing + - utf-8-validate + - viem + - zod + + '@dynamic-labs/store@4.100.5': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + + '@dynamic-labs/sui-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@mysten/sui': 1.45.2(typescript@6.0.3) + '@mysten/wallet-standard': 0.19.9(typescript@6.0.3) + text-encoding: 0.7.0 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + + '@dynamic-labs/sui@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/sui-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/waas-sui': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + text-encoding: 0.7.0 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - viem + + '@dynamic-labs/types@4.100.5': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + + '@dynamic-labs/types@5.13.0': + dependencies: + '@dynamic-labs/assert-package-version': 5.13.0 + '@dynamic-labs/sdk-api-core': 0.136.0 + + '@dynamic-labs/utils@4.100.5': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + buffer: 6.0.3 + eventemitter3: 5.0.1 + tldts: 6.0.16 + + '@dynamic-labs/utils@5.13.0': + dependencies: + '@dynamic-labs/assert-package-version': 5.13.0 + '@dynamic-labs/logger': 5.13.0 + '@dynamic-labs/sdk-api-core': 0.136.0 + '@dynamic-labs/types': 5.13.0 + buffer: 6.0.3 + eventemitter3: 5.0.1 + tldts: 6.0.16 + + '@dynamic-labs/waas-evm@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/ethereum-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/ethereum-gasless-core': 4.100.5(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/waas': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - zod + + '@dynamic-labs/waas-sui@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))': + dependencies: + '@dynamic-labs-sdk/client': 1.39.1(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs-wallet/browser-wallet-client': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/sui-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/waas': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@mysten/sui': 1.45.2(typescript@6.0.3) + '@mysten/wallet-standard': 0.19.9(typescript@6.0.3) + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - viem + + '@dynamic-labs/waas-svm@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/embedded-wallet-solana': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/solana-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/waas': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + bs58: 5.0.0 + eventemitter3: 5.0.1 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - viem + - zod + + '@dynamic-labs/waas@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))': + dependencies: + '@dynamic-labs-sdk/client': 1.39.1(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs-wallet/browser-wallet-client': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/core': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/ethereum-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/solana-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/sui-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/wallet-connector-core': 4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - typescript + - utf-8-validate + - viem + + '@dynamic-labs/wallet-book@4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/iconic': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + eventemitter3: 5.0.1 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + util: 0.12.5 + zod: 4.6.7 + + '@dynamic-labs/wallet-connect@4.100.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/sign-client': 2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@dynamic-labs/wallet-connector-core@4.100.5(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6)': + dependencies: + '@dynamic-labs-sdk/client': 1.39.1(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6) + '@dynamic-labs-wallet/browser-wallet-client': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/core': 1.1.33(@dynamic-labs-wallet/forward-mpc-client@2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@dynamic-labs-wallet/forward-mpc-client': 2.0.2(@dynamic-labs-wallet/primitives@1.1.33)(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@dynamic-labs/rpc-providers': 4.100.5 + '@dynamic-labs/sdk-api-core': 0.92.0 + '@dynamic-labs/types': 4.100.5 + '@dynamic-labs/utils': 4.100.5 + '@dynamic-labs/wallet-book': 4.100.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + eventemitter3: 5.0.1 + transitivePeerDependencies: + - '@dynamic-labs-wallet/primitives' + - '@react-native-async-storage/async-storage' + - bufferutil + - debug + - react + - react-dom + - react-native + - react-native-inappbrowser-reborn + - react-native-keychain + - react-native-passkey + - supports-color + - utf-8-validate + + '@dynamic-labs/webauthn@4.100.5': + dependencies: + '@dynamic-labs/assert-package-version': 4.100.5 + '@dynamic-labs/logger': 4.100.5 + '@simplewebauthn/browser': 13.1.0 + '@simplewebauthn/types': 12.0.0 + + '@ecies/ciphers@0.2.6(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emotion/babel-plugin@11.13.5': + dependencies: + '@babel/helper-module-imports': 7.29.7 + '@babel/runtime': 7.29.10 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color + + '@emotion/cache@11.14.0': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + stylis: 4.2.0 + + '@emotion/hash@0.9.2': {} + + '@emotion/is-prop-valid@1.4.0': + dependencies: + '@emotion/memoize': 0.9.0 + + '@emotion/memoize@0.9.0': {} + + '@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.10 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.3.0) + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + hoist-non-react-statics: 3.3.2 + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + transitivePeerDependencies: + - supports-color + + '@emotion/serialize@1.3.3': + dependencies: + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 + csstype: 3.2.3 + + '@emotion/sheet@1.4.0': {} + + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0))(@types/react@19.3.0)(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.10 + '@emotion/babel-plugin': 11.13.5 + '@emotion/is-prop-valid': 1.4.0 + '@emotion/react': 11.14.0(@types/react@19.3.0)(react@19.3.0) + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.3.0) + '@emotion/utils': 1.4.2 + react: 19.3.0 + optionalDependencies: + '@types/react': 19.3.0 + transitivePeerDependencies: + - supports-color + + '@emotion/unitless@0.10.0': {} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.3.0)': + dependencies: + react: 19.3.0 + + '@emotion/utils@1.4.2': {} + + '@emotion/weak-memoize@0.4.0': {} + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true '@esbuild/openharmony-arm64@0.28.2': optional: true @@ -3057,6 +6626,71 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@4.2.0': + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.2.1 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@evervault/wasm-attestation-bindings@0.3.1': {} + + '@gql.tada/cli-utils@1.9.4(@0no-co/graphqlsp@1.18.0(graphql@16.14.2)(typescript@6.0.3))(graphql@16.14.2)(typescript@6.0.3)': + dependencies: + '@0no-co/graphqlsp': 1.18.0(graphql@16.14.2)(typescript@6.0.3) + '@gql.tada/internal': 1.2.2(graphql@16.14.2)(typescript@6.0.3) + graphql: 16.14.2 + typescript: 6.0.3 + + '@gql.tada/internal@1.2.2(graphql@16.14.2)(typescript@6.0.3)': + dependencies: + '@0no-co/graphql.web': 1.3.4(graphql@16.14.2) + graphql: 16.14.2 + typescript: 6.0.3 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.14.2)': + dependencies: + graphql: 16.14.2 + + '@hcaptcha/react-hcaptcha@1.4.4(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@babel/runtime': 7.29.10 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@hey-api/client-fetch@0.8.1': {} + + '@hpke/chacha20poly1305@1.8.0': + dependencies: + '@hpke/common': 1.10.1 + + '@hpke/common@1.10.1': {} + + '@hpke/core@1.9.0': + dependencies: + '@hpke/common': 1.10.1 + + '@hpke/dhkem-x25519@1.8.0': + dependencies: + '@hpke/common': 1.10.1 + + '@hpke/dhkem-x448@1.8.0': + dependencies: + '@hpke/common': 1.10.1 + '@humanfs/core@0.19.2': dependencies: '@humanfs/types': 0.15.0 @@ -3073,7 +6707,11 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@img/colour@1.1.0': + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.0 optional: true '@img/sharp-darwin-arm64@0.35.5': @@ -3081,102 +6719,201 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.3.4 optional: true + '@img/sharp-darwin-x64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.0 + optional: true + '@img/sharp-darwin-x64@0.35.5': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.3.4 optional: true + '@img/sharp-freebsd-wasm32@0.35.0': + dependencies: + '@img/sharp-wasm32': 0.35.0 + optional: true + '@img/sharp-freebsd-wasm32@0.35.5': dependencies: '@img/sharp-wasm32': 0.35.5 optional: true + '@img/sharp-libvips-darwin-arm64@1.3.0': + optional: true + '@img/sharp-libvips-darwin-arm64@1.3.4': optional: true + '@img/sharp-libvips-darwin-x64@1.3.0': + optional: true + '@img/sharp-libvips-darwin-x64@1.3.4': optional: true + '@img/sharp-libvips-linux-arm64@1.3.0': + optional: true + '@img/sharp-libvips-linux-arm64@1.3.4': optional: true + '@img/sharp-libvips-linux-arm@1.3.0': + optional: true + '@img/sharp-libvips-linux-arm@1.3.4': optional: true + '@img/sharp-libvips-linux-ppc64@1.3.0': + optional: true + '@img/sharp-libvips-linux-ppc64@1.3.4': optional: true + '@img/sharp-libvips-linux-riscv64@1.3.0': + optional: true + '@img/sharp-libvips-linux-riscv64@1.3.4': optional: true + '@img/sharp-libvips-linux-s390x@1.3.0': + optional: true + '@img/sharp-libvips-linux-s390x@1.3.4': optional: true + '@img/sharp-libvips-linux-x64@1.3.0': + optional: true + '@img/sharp-libvips-linux-x64@1.3.4': optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.3.0': + optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': optional: true + '@img/sharp-libvips-linuxmusl-x64@1.3.0': + optional: true + '@img/sharp-libvips-linuxmusl-x64@1.3.4': optional: true + '@img/sharp-linux-arm64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.0 + optional: true + '@img/sharp-linux-arm64@0.35.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.3.4 optional: true + '@img/sharp-linux-arm@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.0 + optional: true + '@img/sharp-linux-arm@0.35.5': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.3.4 optional: true + '@img/sharp-linux-ppc64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.0 + optional: true + '@img/sharp-linux-ppc64@0.35.5': optionalDependencies: '@img/sharp-libvips-linux-ppc64': 1.3.4 optional: true + '@img/sharp-linux-riscv64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.0 + optional: true + '@img/sharp-linux-riscv64@0.35.5': optionalDependencies: '@img/sharp-libvips-linux-riscv64': 1.3.4 optional: true + '@img/sharp-linux-s390x@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.0 + optional: true + '@img/sharp-linux-s390x@0.35.5': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.3.4 optional: true + '@img/sharp-linux-x64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.0 + optional: true + '@img/sharp-linux-x64@0.35.5': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.3.4 optional: true + '@img/sharp-linuxmusl-arm64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.0 + optional: true + '@img/sharp-linuxmusl-arm64@0.35.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 optional: true + '@img/sharp-linuxmusl-x64@0.35.0': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.0 + optional: true + '@img/sharp-linuxmusl-x64@0.35.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.3.4 optional: true + '@img/sharp-wasm32@0.35.0': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + '@img/sharp-wasm32@0.35.5': dependencies: '@emnapi/runtime': 1.11.3 optional: true + '@img/sharp-webcontainers-wasm32@0.35.0': + dependencies: + '@img/sharp-wasm32': 0.35.0 + optional: true + '@img/sharp-webcontainers-wasm32@0.35.5': dependencies: '@img/sharp-wasm32': 0.35.5 optional: true + '@img/sharp-win32-arm64@0.35.0': + optional: true + '@img/sharp-win32-arm64@0.35.5': optional: true + '@img/sharp-win32-ia32@0.35.0': + optional: true + '@img/sharp-win32-ia32@0.35.5': optional: true + '@img/sharp-win32-x64@0.35.0': + optional: true + '@img/sharp-win32-x64@0.35.5': optional: true @@ -3199,6 +6936,225 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.6.0 + '@lit-labs/ssr-dom-shim@1.6.0': {} + + '@lit/react@1.0.8(@types/react@19.3.0)': + dependencies: + '@types/react': 19.3.0 + optional: true + + '@lit/reactive-element@2.1.2': + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + + '@marsidev/react-turnstile@1.5.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@metamask/analytics@0.6.0': + dependencies: + openapi-fetch: 0.13.8 + + '@metamask/connect-evm@2.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@metamask/analytics': 0.6.0 + '@metamask/connect-multichain': 1.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@metamask/utils': 11.12.1 + semver: 7.8.5 + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/connect-multichain@1.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@metamask/analytics': 0.6.0 + '@metamask/mobile-wallet-protocol-core': 0.4.0 + '@metamask/mobile-wallet-protocol-dapp-client': 0.3.0 + '@metamask/multichain-api-client': 0.10.1 + '@metamask/multichain-ui': 0.4.1 + '@metamask/onboarding': 1.0.1 + '@metamask/rpc-errors': 7.0.3 + '@metamask/utils': 11.12.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.15.0 + buffer: 6.0.3 + cross-fetch: 4.1.0 + eciesjs: 0.4.17 + eventemitter3: 5.0.1 + pako: 2.2.0 + uuid: 11.1.1 + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/connect-multichain@1.2.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@metamask/analytics': 0.6.0 + '@metamask/mobile-wallet-protocol-core': 0.4.0 + '@metamask/mobile-wallet-protocol-dapp-client': 0.3.0 + '@metamask/multichain-api-client': 0.10.1 + '@metamask/multichain-ui': 0.4.1 + '@metamask/onboarding': 1.0.1 + '@metamask/rpc-errors': 7.0.3 + '@metamask/utils': 11.12.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.15.0 + buffer: 6.0.3 + cross-fetch: 4.1.0 + eciesjs: 0.4.17 + eventemitter3: 5.0.1 + pako: 2.2.0 + uuid: 11.1.1 + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/connect-solana@2.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@metamask/connect-multichain': 1.2.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@metamask/solana-wallet-standard': 0.6.0 + '@wallet-standard/app': 1.1.1 + '@wallet-standard/base': 1.1.1 + semver: 7.8.5 + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/mobile-wallet-protocol-core@0.4.0': + dependencies: + async-mutex: 0.5.0 + centrifuge: 5.8.0 + eventemitter3: 5.0.1 + uuid: 11.1.1 + + '@metamask/mobile-wallet-protocol-dapp-client@0.3.0': + dependencies: + '@metamask/mobile-wallet-protocol-core': 0.4.0 + '@metamask/utils': 9.3.0 + uuid: 11.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/multichain-api-client@0.10.1': {} + + '@metamask/multichain-ui@0.4.1': + dependencies: + '@paulmillr/qr': 0.2.1 + qr-code-styling: 1.9.2 + + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.15.0 + + '@metamask/rpc-errors@7.0.3': + dependencies: + '@metamask/utils': 11.12.1 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/scure-bip39@2.1.1': + dependencies: + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.9 + + '@metamask/solana-wallet-standard@0.6.0': + dependencies: + '@solana/wallet-standard-chains': 1.1.2 + '@solana/wallet-standard-features': 1.5.0 + '@wallet-standard/base': 1.1.1 + '@wallet-standard/features': 1.1.1 + '@wallet-standard/wallet': 1.1.1 + bs58: 6.0.0 + + '@metamask/superstruct@3.4.1': {} + + '@metamask/utils@11.12.1': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/scure-bip39': 2.1.1 + '@metamask/superstruct': 3.4.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.13 + '@types/lodash': 4.17.27 + debug: 4.4.3 + lodash: 4.18.1 + pony-cause: 2.1.11 + semver: 7.8.5 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@9.3.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.4.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.13 + debug: 4.4.3 + pony-cause: 2.1.11 + semver: 7.8.5 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@msgpack/msgpack@3.1.2': {} + + '@mysten/bcs@1.9.2': + dependencies: + '@mysten/utils': 0.2.0 + '@scure/base': 1.2.6 + + '@mysten/sui@1.45.2(typescript@6.0.3)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.14.2) + '@mysten/bcs': 1.9.2 + '@mysten/utils': 0.2.0 + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 + '@protobuf-ts/grpcweb-transport': 2.11.1 + '@protobuf-ts/runtime': 2.11.1 + '@protobuf-ts/runtime-rpc': 2.11.1 + '@scure/base': 1.2.6 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + gql.tada: 1.11.4(graphql@16.14.2)(typescript@6.0.3) + graphql: 16.14.2 + poseidon-lite: 0.2.1 + valibot: 1.5.0(typescript@6.0.3) + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - typescript + + '@mysten/utils@0.2.0': + dependencies: + '@scure/base': 1.2.6 + + '@mysten/wallet-standard@0.19.9(typescript@6.0.3)': + dependencies: + '@mysten/sui': 1.45.2(typescript@6.0.3) + '@wallet-standard/core': 1.1.1 + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - typescript + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 @@ -3239,6 +7195,59 @@ snapshots: '@next/swc-win32-x64-msvc@16.4.3': optional: true + '@noble/ciphers@0.4.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.9.0': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.2': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.4': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@2.0.1': + dependencies: + '@noble/hashes': 2.0.1 + + '@noble/hashes@1.3.3': {} + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.8.0': {} + + '@noble/hashes@2.0.1': {} + + '@noble/hashes@2.4.0': {} + + '@noble/post-quantum@0.5.4': + dependencies: + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3262,8 +7271,301 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} + '@openzeppelin/contracts@4.9.6': {} + '@oxc-project/types@0.153.0': {} + '@paulmillr/qr@0.2.1': {} + + '@phosphor-icons/webcomponents@2.1.5': + dependencies: + lit: 3.3.0 + + '@protobuf-ts/grpcweb-transport@2.11.1': + dependencies: + '@protobuf-ts/runtime': 2.11.1 + '@protobuf-ts/runtime-rpc': 2.11.1 + + '@protobuf-ts/runtime-rpc@2.11.1': + dependencies: + '@protobuf-ts/runtime': 2.11.1 + + '@protobuf-ts/runtime@2.11.1': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.1': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.2': {} + + '@reown/appkit-common@1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-wallet': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@walletconnect/universal-provider': 2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + valtio: 2.1.7(@types/react@19.3.0)(react@19.3.0) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-pay@1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-controllers': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-ui': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-utils': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@19.3.0)(react@19.3.0))(zod@3.22.4) + lit: 3.3.0 + valtio: 2.1.7(@types/react@19.3.0)(react@19.3.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-polyfills@1.8.11': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-ui@1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@19.3.0)(react@19.3.0))(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-controllers': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-ui': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-utils': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@19.3.0)(react@19.3.0))(zod@3.22.4) + '@reown/appkit-wallet': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + lit: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - valtio + - zod + + '@reown/appkit-ui@1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@phosphor-icons/webcomponents': 2.1.5 + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-controllers': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-wallet': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + lit: 3.3.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-utils@1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@19.3.0)(react@19.3.0))(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-controllers': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-polyfills': 1.8.11 + '@reown/appkit-wallet': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@wallet-standard/wallet': 1.1.0 + '@walletconnect/logger': 3.0.2 + '@walletconnect/universal-provider': 2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + valtio: 2.1.7(@types/react@19.3.0)(react@19.3.0) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-wallet@1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-polyfills': 1.8.11 + '@walletconnect/logger': 3.0.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-controllers': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-pay': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-polyfills': 1.8.11 + '@reown/appkit-scaffold-ui': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@19.3.0)(react@19.3.0))(zod@3.22.4) + '@reown/appkit-ui': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@reown/appkit-utils': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@19.3.0)(react@19.3.0))(zod@3.22.4) + '@reown/appkit-wallet': 1.8.11(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@walletconnect/universal-provider': 2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + bs58: 6.0.0 + semver: 7.7.2 + valtio: 2.1.7(@types/react@19.3.0)(react@19.3.0) + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + optionalDependencies: + '@lit/react': 1.0.8(@types/react@19.3.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + '@rolldown/binding-android-arm-eabi@1.2.13': optional: true @@ -3313,6 +7615,188 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@scure/base@1.1.9': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.4 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@simplewebauthn/browser@13.1.0': {} + + '@simplewebauthn/types@12.0.0': {} + + '@sindresorhus/is@4.6.0': {} + + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + bigint-buffer: 1.1.5 + bignumber.js: 9.3.1 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/codecs-core@2.0.0-rc.1(typescript@6.0.3)': + dependencies: + '@solana/errors': 2.0.0-rc.1(typescript@6.0.3) + typescript: 6.0.3 + + '@solana/codecs-core@2.3.0(typescript@6.0.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@6.0.3) + typescript: 6.0.3 + + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@6.0.3)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@6.0.3) + '@solana/errors': 2.0.0-rc.1(typescript@6.0.3) + typescript: 6.0.3 + + '@solana/codecs-numbers@2.0.0-rc.1(typescript@6.0.3)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@6.0.3) + '@solana/errors': 2.0.0-rc.1(typescript@6.0.3) + typescript: 6.0.3 + + '@solana/codecs-numbers@2.3.0(typescript@6.0.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@6.0.3) + '@solana/errors': 2.3.0(typescript@6.0.3) + typescript: 6.0.3 + + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@6.0.3) + '@solana/errors': 2.0.0-rc.1(typescript@6.0.3) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 6.0.3 + + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.0.0-rc.1(typescript@6.0.3)': + dependencies: + chalk: 5.6.2 + commander: 12.1.0 + typescript: 6.0.3 + + '@solana/errors@2.3.0(typescript@6.0.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.3 + typescript: 6.0.3 + + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@6.0.3) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + '@solana/errors': 2.0.0-rc.1(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)': + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)': + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@solana/spl-token@0.4.14(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@6.0.3) + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + '@solana/wallet-standard-chains@1.1.2': + dependencies: + '@wallet-standard/base': 1.1.1 + + '@solana/wallet-standard-features@1.5.0': + dependencies: + '@wallet-standard/base': 1.1.1 + '@wallet-standard/features': 1.1.1 + + '@solana/web3.js@1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)': + dependencies: + '@babel/runtime': 7.29.10 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.3.0(typescript@6.0.3) + agentkeepalive: 4.6.0 + bn.js: 5.2.5 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + node-fetch: 2.7.0 + rpc-websockets: 9.3.9 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + '@standard-schema/spec@1.1.0': {} '@stripe/link-integrations-eve@0.3.4(eve@0.79.1(@opentelemetry/api@1.9.1)(ai@7.0.137(zod@4.6.7))(microsandbox@0.5.10))': @@ -3338,29 +7822,179 @@ snapshots: dependencies: tslib: 2.8.1 + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + + '@thumbmarkjs/thumbmarkjs@0.16.0': {} + + '@turnkey/api-key-stamper@0.4.7': + dependencies: + '@noble/curves': 1.9.7 + '@turnkey/encoding': 0.5.0 + sha256-uint8array: 0.10.7 + + '@turnkey/crypto@2.5.0': + dependencies: + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 + '@turnkey/encoding': 0.5.0 + bs58: 6.0.0 + bs58check: 4.0.0 + + '@turnkey/encoding@0.5.0': {} + + '@turnkey/http@3.10.0': + dependencies: + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/encoding': 0.5.0 + '@turnkey/webauthn-stamper': 0.5.1 + cross-fetch: 3.2.0 + transitivePeerDependencies: + - encoding + + '@turnkey/iframe-stamper@2.5.0': {} + + '@turnkey/indexed-db-stamper@1.1.1': + dependencies: + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/encoding': 0.5.0 + + '@turnkey/sdk-browser@5.8.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/crypto': 2.5.0 + '@turnkey/encoding': 0.5.0 + '@turnkey/http': 3.10.0 + '@turnkey/iframe-stamper': 2.5.0 + '@turnkey/indexed-db-stamper': 1.1.1 + '@turnkey/sdk-types': 0.3.0 + '@turnkey/wallet-stamper': 1.0.8(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@turnkey/webauthn-stamper': 0.5.1 + bs58check: 4.0.0 + buffer: 6.0.3 + cross-fetch: 3.2.0 + hpke-js: 1.8.0 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@turnkey/sdk-server@4.7.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/http': 3.10.0 + '@turnkey/wallet-stamper': 1.0.8(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + buffer: 6.0.3 + cross-fetch: 3.2.0 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@turnkey/sdk-types@0.3.0': {} + + '@turnkey/solana@1.0.42(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@solana/web3.js': 1.98.1(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6) + '@turnkey/http': 3.10.0 + '@turnkey/sdk-browser': 5.8.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@turnkey/sdk-server': 4.7.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@turnkey/viem@0.13.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4))(zod@3.22.4)': + dependencies: + '@noble/curves': 1.8.0 + '@openzeppelin/contracts': 4.9.6 + '@turnkey/api-key-stamper': 0.4.7 + '@turnkey/http': 3.10.0 + '@turnkey/sdk-browser': 5.8.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@turnkey/sdk-server': 4.7.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + cross-fetch: 4.1.0 + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@turnkey/wallet-stamper@1.0.8(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@turnkey/crypto': 2.5.0 + '@turnkey/encoding': 0.5.0 + optionalDependencies: + viem: 2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@turnkey/webauthn-stamper@0.5.1': + dependencies: + sha256-uint8array: 0.10.7 + '@tybys/wasm-util@0.10.4': dependencies: tslib: 2.8.1 optional: true + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.2.0 + '@types/keyv': 3.1.4 + '@types/node': 24.19.0 + '@types/responselike': 1.0.3 + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/connect@3.4.38': + dependencies: + '@types/node': 24.19.0 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} '@types/estree@1.0.9': {} + '@types/http-cache-semantics@4.2.0': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/keyv@3.1.4': + dependencies: + '@types/node': 24.19.0 + + '@types/lodash@4.17.27': {} + + '@types/ms@2.1.0': {} + '@types/node-fetch@2.6.13': dependencies: '@types/node': 24.19.0 form-data: 4.0.6 + '@types/node@12.20.55': {} + '@types/node@18.19.130': dependencies: undici-types: 5.26.5 @@ -3369,6 +8003,8 @@ snapshots: dependencies: undici-types: 7.24.6 + '@types/parse-json@4.0.2': {} + '@types/pg@8.23.1': dependencies: '@types/node': 24.19.0 @@ -3383,6 +8019,22 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/responselike@1.0.3': + dependencies: + '@types/node': 24.19.0 + + '@types/trusted-types@2.0.7': {} + + '@types/uuid@10.0.0': {} + + '@types/ws@7.4.7': + dependencies: + '@types/node': 24.19.0 + + '@types/ws@8.18.2': + dependencies: + '@types/node': 24.19.0 + '@typescript-eslint/eslint-plugin@8.71.1(@typescript-eslint/parser@8.71.1(eslint@9.39.5)(typescript@6.0.3))(eslint@9.39.5)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -3587,8 +8239,800 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.2.0 + '@vue/reactivity@3.5.44': + dependencies: + '@vue/shared': 3.5.44 + + '@vue/shared@3.5.44': {} + + '@wallet-standard/app@1.0.1': + dependencies: + '@wallet-standard/base': 1.0.1 + + '@wallet-standard/app@1.1.1': + dependencies: + '@wallet-standard/base': 1.1.1 + + '@wallet-standard/base@1.0.1': {} + + '@wallet-standard/base@1.1.1': {} + + '@wallet-standard/core@1.1.1': + dependencies: + '@wallet-standard/app': 1.1.1 + '@wallet-standard/base': 1.1.1 + '@wallet-standard/errors': 0.1.2 + '@wallet-standard/features': 1.1.1 + '@wallet-standard/wallet': 1.1.1 + + '@wallet-standard/errors@0.1.2': + dependencies: + chalk: 5.6.2 + commander: 13.1.0 + + '@wallet-standard/experimental-features@0.1.1': + dependencies: + '@wallet-standard/base': 1.0.1 + + '@wallet-standard/features@1.0.3': + dependencies: + '@wallet-standard/base': 1.0.1 + + '@wallet-standard/features@1.1.1': + dependencies: + '@wallet-standard/base': 1.1.1 + + '@wallet-standard/wallet@1.1.0': + dependencies: + '@wallet-standard/base': 1.1.1 + + '@wallet-standard/wallet@1.1.1': + dependencies: + '@wallet-standard/base': 1.1.1 + + '@walletconnect/core@2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.5(db0@0.4.1) + '@walletconnect/utils': 2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.39.3 + events: 3.3.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.0 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.22.4(db0@0.4.1) + '@walletconnect/utils': 2.22.4(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.39.3 + events: 3.3.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.23.2(db0@0.4.1) + '@walletconnect/utils': 2.23.2(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.39.3 + events: 3.3.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.23.2(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@reown/appkit': 1.8.11(@types/react@19.3.0)(bufferutil@4.1.0)(db0@0.4.1)(react@19.3.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.2 + '@walletconnect/sign-client': 2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/types': 2.23.2(db0@0.4.1) + '@walletconnect/universal-provider': 2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/utils': 2.23.2(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.2.0 + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1(db0@0.4.1)': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.3.0 + unstorage: 1.17.6(db0@0.4.1)(idb-keyval@6.3.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/logger@3.0.0': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 10.0.0 + + '@walletconnect/logger@3.0.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 10.0.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.1 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/core': 2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.5(db0@0.4.1) + '@walletconnect/utils': 2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/core': 2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 3.0.0 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.22.4(db0@0.4.1) + '@walletconnect/utils': 2.22.4(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/core': 2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 3.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.23.2(db0@0.4.1) + '@walletconnect/utils': 2.23.2(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.21.5(db0@0.4.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/types@2.22.4(db0@0.4.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/types@2.23.2(db0@0.4.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/universal-provider@2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.0 + '@walletconnect/sign-client': 2.22.4(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/types': 2.22.4(db0@0.4.1) + '@walletconnect/utils': 2.22.4(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + es-toolkit: 1.39.3 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.2 + '@walletconnect/sign-client': 2.23.2(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + '@walletconnect/types': 2.23.2(db0@0.4.1) + '@walletconnect/utils': 2.23.2(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4) + es-toolkit: 1.39.3 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.5(bufferutil@4.1.0)(db0@0.4.1)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4)': + dependencies: + '@msgpack/msgpack': 3.1.2 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.5(db0@0.4.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + blakejs: 1.2.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.1 + viem: 2.31.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.22.4(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4)': + dependencies: + '@msgpack/msgpack': 3.1.2 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.0 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.22.4(db0@0.4.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + blakejs: 1.2.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + ox: 0.9.3(typescript@6.0.3)(zod@3.22.4) + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - typescript + - uploadthing + - zod + + '@walletconnect/utils@2.23.2(db0@0.4.1)(typescript@6.0.3)(zod@3.22.4)': + dependencies: + '@msgpack/msgpack': 3.1.2 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(db0@0.4.1) + '@walletconnect/logger': 3.0.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.23.2(db0@0.4.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + blakejs: 1.2.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + ox: 0.9.3(typescript@6.0.3)(zod@3.22.4) + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - typescript + - uploadthing + - zod + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + '@workflow/serde@4.1.0': {} + abitype@1.0.8(typescript@6.0.3)(zod@3.22.4): + optionalDependencies: + typescript: 6.0.3 + zod: 3.22.4 + + abitype@1.2.3(typescript@6.0.3)(zod@3.22.4): + optionalDependencies: + typescript: 6.0.3 + zod: 3.22.4 + + abitype@1.2.3(typescript@6.0.3)(zod@4.6.7): + optionalDependencies: + typescript: 6.0.3 + zod: 4.6.7 + + abitype@1.3.0(typescript@6.0.3)(zod@3.22.4): + optionalDependencies: + typescript: 6.0.3 + zod: 3.22.4 + + ably@2.17.1(bufferutil@4.1.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(utf-8-validate@6.0.6): + dependencies: + '@ably/msgpack-js': 0.4.1 + dequal: 2.0.3 + fastestsmallesttextencoderdecoder: 1.0.22 + got: 11.8.6 + ulid: 2.4.0 + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -3599,6 +9043,12 @@ snapshots: acorn@8.19.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 @@ -3617,10 +9067,17 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + argparse@2.0.1: {} aria-query@5.3.2: {} @@ -3698,22 +9155,87 @@ snapshots: async-function@1.0.0: {} + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + asynckit@0.4.0: {} + atomic-sleep@1.0.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 axe-core@4.14.0: {} + axios@1.20.0: + dependencies: + follow-redirects: 1.16.2 + form-data: 4.0.6 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + axobject-query@4.1.0: {} + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.29.10 + cosmiconfig: 7.1.0 + resolve: 1.22.13 + balanced-match@1.0.2: {} balanced-match@4.0.4: {} + base-x@3.0.11: + dependencies: + safe-buffer: 5.2.1 + + base-x@4.0.1: {} + + base-x@5.0.1: {} + + base32.js@0.1.0: {} + + base64-js@1.0.2: {} + + base64-js@1.5.1: {} + baseline-browser-mapping@2.11.27: {} + big.js@6.2.2: {} + + bigint-buffer@1.1.5: + dependencies: + bindings: 1.5.0 + + bignumber.js@9.3.1: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + blakejs@1.2.1: {} + + bn.js@5.2.5: {} + + bops@1.0.1: + dependencies: + base64-js: 1.0.2 + to-utf8: 0.0.1 + + borsh@0.7.0: + dependencies: + bn.js: 5.2.5 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + + bowser@2.15.0: {} + brace-expansion@1.1.21: dependencies: balanced-match: 1.0.2 @@ -3735,6 +9257,45 @@ snapshots: node-releases: 2.0.57 update-browserslist-db: 1.3.4(browserslist@4.29.3) + bs58@4.0.1: + dependencies: + base-x: 3.0.11 + + bs58@5.0.0: + dependencies: + base-x: 4.0.1 + + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + + bs58check@4.0.0: + dependencies: + '@noble/hashes': 1.8.0 + bs58: 6.0.0 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.1.0: + dependencies: + node-gyp-build: 4.8.4 + optional: true + + cacheable-lookup@5.0.4: {} + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.3.0 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -3754,8 +9315,15 @@ snapshots: callsites@3.1.0: {} + camelcase@5.3.1: {} + caniuse-lite@1.0.30001815: {} + centrifuge@5.8.0: + dependencies: + events: 3.3.0 + protobufjs: 7.6.6 + chai@6.3.0: {} chalk@4.1.2: @@ -3763,30 +9331,100 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + client-only@0.0.1: {} + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + clsx@1.2.1: {} + + clsx@2.1.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 + commander@12.1.0: {} + + commander@13.1.0: {} + + commander@14.0.3: {} + + commander@2.20.3: {} + concat-map@0.0.1: {} consola@3.4.2: {} + convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} + cookie-es@1.2.3: {} + + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.3 + + country-list@2.3.0: {} + + crc-32@1.2.2: {} + + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + crossws@0.4.15(srvx@1.0.5): optionalDependencies: srvx: 1.0.5 @@ -3813,6 +9451,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dayjs@1.11.13: {} + db0@0.4.1: {} debug@3.2.7: @@ -3823,8 +9463,20 @@ snapshots: dependencies: ms: 2.1.3 + decamelize@1.2.0: {} + + decode-uri-component@0.2.2: {} + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + deep-is@0.1.4: {} + deepmerge@2.2.1: {} + + defer-to-connect@2.0.1: {} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -3837,24 +9489,65 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + defu@6.1.7: {} + + delay@5.0.0: {} + delayed-stream@1.0.0: {} + dequal@2.0.3: {} + + destr@2.0.5: {} + + detect-browser@5.3.0: {} + detect-libc@2.1.2: {} + detect-node-es@1.1.0: {} + + dijkstrajs@1.0.3: {} + doctrine@2.1.0: dependencies: esutils: 2.0.3 + dom-helpers@5.2.1: + dependencies: + '@babel/runtime': 7.29.10 + csstype: 3.2.3 + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 es-errors: 1.3.0 gopd: 1.2.0 + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + eciesjs@0.4.17: + dependencies: + '@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + electron-to-chromium@1.5.451: {} + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + encode-utf8@1.0.3: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + env-runner@0.2.3: dependencies: crossws: 0.4.15(srvx@1.0.5) @@ -3862,6 +9555,10 @@ snapshots: httpxy: 0.5.5 srvx: 1.0.5 + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + es-abstract-get@1.0.0: dependencies: es-errors: 1.3.0 @@ -3975,6 +9672,14 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.39.3: {} + + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + esbuild@0.28.2: optionalDependencies: '@esbuild/aix-ppc64': 0.28.2 @@ -4216,6 +9921,13 @@ snapshots: esutils@2.0.3: {} + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + eve@0.79.1(@opentelemetry/api@1.9.1)(ai@7.0.137(zod@4.6.7))(microsandbox@0.5.10): dependencies: ai: 7.0.137(zod@4.6.7) @@ -4227,12 +9939,20 @@ snapshots: event-target-shim@5.0.1: {} + eventemitter3@5.0.1: {} + + events@3.3.0: {} + eventsource-parser@3.1.1: {} expect-type@1.4.0: {} + exponential-backoff@3.1.1: {} + exsolve@1.1.3: {} + eyes@0.1.8: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.1: @@ -4247,6 +9967,14 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fast-stable-stringify@1.0.0: {} + + fastestsmallesttextencoderdecoder@1.0.22: {} + fastq@1.20.3: dependencies: reusify: 1.1.0 @@ -4259,10 +9987,21 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + filter-obj@1.1.0: {} + + find-root@1.1.0: {} + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -4275,6 +10014,12 @@ snapshots: flatted@3.4.4: {} + focus-lock@1.3.6: + dependencies: + tslib: 2.8.1 + + follow-redirects@1.16.2: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -4294,6 +10039,19 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 4.0.0-beta.3 + formik@2.2.9(react@19.3.0): + dependencies: + deepmerge: 2.2.1 + hoist-non-react-statics: 3.3.2 + lodash: 4.18.1 + lodash-es: 4.18.1 + react: 19.3.0 + react-fast-compare: 2.0.4 + tiny-warning: 1.0.3 + tslib: 1.14.1 + + fp-ts@2.16.11: {} + fsevents@2.3.3: optional: true @@ -4317,6 +10075,8 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -4335,6 +10095,10 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.2 + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 @@ -4364,6 +10128,46 @@ snapshots: gopd@1.2.0: {} + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + + gql.tada@1.11.4(graphql@16.14.2)(typescript@6.0.3): + dependencies: + '@0no-co/graphql.web': 1.3.4(graphql@16.14.2) + '@0no-co/graphqlsp': 1.18.0(graphql@16.14.2)(typescript@6.0.3) + '@gql.tada/cli-utils': 1.9.4(@0no-co/graphqlsp@1.18.0(graphql@16.14.2)(typescript@6.0.3))(graphql@16.14.2)(typescript@6.0.3) + '@gql.tada/internal': 1.2.2(graphql@16.14.2)(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - graphql + + graphql@16.14.2: {} + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.5 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + h3@2.0.2(crossws@0.4.15(srvx@1.0.5))(ocache@0.3.0): dependencies: rou3: 1.0.0 @@ -4400,14 +10204,54 @@ snapshots: dependencies: hermes-estree: 0.25.1 + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + hookable@6.1.2: {} + hpke-js@1.8.0: + dependencies: + '@hpke/chacha20poly1305': 1.8.0 + '@hpke/common': 1.10.1 + '@hpke/core': 1.9.0 + '@hpke/dhkem-x25519': 1.8.0 + '@hpke/dhkem-x448': 1.8.0 + + html-parse-stringify@3.1.0: + dependencies: + void-elements: 3.1.0 + + http-cache-semantics@4.3.0: {} + + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + httpxy@0.5.5: {} humanize-ms@1.2.1: dependencies: ms: 2.1.3 + i18next@23.4.6: + dependencies: + '@babel/runtime': 7.29.10 + + idb-keyval@6.2.1: {} + + idb-keyval@6.3.0: {} + + ieee754@1.2.1: {} + ignore@5.3.2: {} ignore@7.0.12: {} @@ -4419,18 +10263,40 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: {} + + input-otp@1.4.2(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.4 side-channel: 1.1.1 + io-ts@2.2.22(fp-ts@2.16.11): + dependencies: + fp-ts: 2.16.11 + + iron-webcrypto@1.2.1: {} + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 get-intrinsic: 1.3.0 + is-arrayish@0.2.1: {} + + is-arrayish@0.3.4: {} + is-async-function@2.1.1: dependencies: async-function: 1.0.0 @@ -4479,6 +10345,8 @@ snapshots: dependencies: call-bound: 1.0.4 + is-fullwidth-code-point@3.0.0: {} + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 @@ -4545,6 +10413,26 @@ snapshots: isexe@2.0.0: {} + isomorphic-ws@4.0.1(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + dependencies: + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + isows@1.0.7(ws@8.18.2(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + dependencies: + ws: 8.18.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + isows@1.0.7(ws@8.18.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + dependencies: + ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + isows@1.0.7(ws@8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + dependencies: + ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + isows@1.0.7(ws@8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + dependencies: + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -4554,6 +10442,24 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 + jayson@4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + json-stringify-safe: 5.0.1 + stream-json: 1.9.1 + uuid: 8.3.2 + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + js-tokens@4.0.0: {} js-yaml@4.3.2: @@ -4564,12 +10470,16 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} json-schema@0.4.0: {} json-stable-stringify-without-jsonify@1.0.1: {} + json-stringify-safe@5.0.1: {} + json5@1.0.2: dependencies: minimist: 1.2.8 @@ -4583,10 +10493,14 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 + jwt-decode@4.0.0: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + keyvaluestorage-interface@1.0.0: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -4647,16 +10561,52 @@ snapshots: lightningcss-win32-arm64-msvc: 1.33.0 lightningcss-win32-x64-msvc: 1.33.0 + lines-and-columns@1.2.4: {} + + lit-element@4.2.2: + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + '@lit/reactive-element': 2.1.2 + lit-html: 3.3.3 + + lit-html@3.3.3: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@3.3.0: + dependencies: + '@lit/reactive-element': 2.1.2 + lit-element: 4.2.2 + lit-html: 3.3.3 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 + lodash-es@4.18.1: {} + + lodash.clonedeep@4.5.0: {} + + lodash.isequal@4.5.0: {} + lodash.merge@4.6.2: {} + lodash@4.18.1: {} + + long@5.3.2: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 + lowercase-keys@2.0.0: {} + + lru-cache@11.5.3: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -4669,6 +10619,8 @@ snapshots: merge2@1.4.1: {} + micro-ftch@0.3.1: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4687,6 +10639,10 @@ snapshots: dependencies: mime-db: 1.52.0 + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + minimatch@10.2.6: dependencies: brace-expansion: 5.0.12 @@ -4699,6 +10655,10 @@ snapshots: ms@2.1.3: {} + multiformats@9.9.0: {} + + nanoclone@0.2.1: {} + nanoid@3.3.20: {} napi-postinstall@0.3.4: {} @@ -4758,12 +10718,23 @@ snapshots: object.entries: 1.1.9 semver: 6.3.1 + node-fetch-native@1.6.7: {} + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 + node-gyp-build@4.8.4: + optional: true + + node-mock-http@1.0.5: {} + node-releases@2.0.57: {} + normalize-path@3.0.0: {} + + normalize-url@6.1.0: {} + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -4801,14 +10772,34 @@ snapshots: object.values@1.2.1: dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.2 + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + obug@2.2.1: {} + + ocache@0.3.0: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + on-exit-leak-free@0.2.0: {} + + on-exit-leak-free@2.1.2: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 - obug@2.2.1: {} + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 - ocache@0.3.0: {} + openapi-typescript-helpers@0.0.15: {} optionator@0.9.4: dependencies: @@ -4826,24 +10817,136 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + ox@0.12.4(typescript@6.0.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod + + ox@0.14.56(typescript@6.0.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod + + ox@0.14.56(typescript@6.0.3)(zod@4.6.7): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@4.6.7) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@6.0.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.3.0(typescript@6.0.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod + + ox@0.7.1(typescript@6.0.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@6.0.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod + + ox@0.9.3(typescript@6.0.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.3.0(typescript@6.0.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod + + p-cancelable@2.1.1: {} + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-try@2.2.0: {} + + pako@2.2.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.7 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + path-exists@4.0.0: {} path-key@3.1.1: {} path-parse@1.0.7: {} + path-type@4.0.0: {} + pathe@2.0.3: {} pg-cloudflare@1.4.1: @@ -4887,8 +10990,55 @@ snapshots: picomatch@4.0.7: {} + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino-std-serializers@7.1.0: {} + + pino@10.0.0: + dependencies: + atomic-sleep: 1.0.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.1.1 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + slow-redact: 0.3.2 + sonic-boom: 4.2.1 + thread-stream: 3.2.0 + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + playwright-core@1.62.1: {} + pngjs@5.0.0: {} + + pony-cause@2.1.11: {} + + poseidon-lite@0.2.1: {} + possible-typed-array-names@1.1.0: {} postcss@8.5.23: @@ -4913,27 +11063,150 @@ snapshots: dependencies: xtend: 4.0.2 + preact@10.24.2: {} + + preact@10.29.8: {} + prelude-ls@1.2.1: {} + process-warning@1.0.0: {} + + process-warning@5.1.1: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 + property-expr@2.0.6: {} + + protobufjs@7.6.6: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.1 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.2 + '@types/node': 24.19.0 + long: 5.3.2 + + proxy-compare@3.0.1: {} + + proxy-from-env@2.1.0: {} + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@1.3.2: {} + punycode@2.3.1: {} + qr-code-styling@1.9.2: + dependencies: + qrcode-generator: 1.5.2 + + qrcode-generator@1.5.2: {} + + qrcode@1.5.1: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + + querystring@0.2.0: {} + queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} + + quick-lru@5.1.1: {} + + radix3@1.1.2: {} + + react-clientside-effect@1.2.8(react@19.3.0): + dependencies: + '@babel/runtime': 7.29.10 + react: 19.3.0 + react-dom@19.3.0(react@19.3.0): dependencies: react: 19.3.0 scheduler: 0.28.0 + react-fast-compare@2.0.4: {} + + react-focus-lock@2.13.6(@types/react@19.3.0)(react@19.3.0): + dependencies: + '@babel/runtime': 7.29.10 + focus-lock: 1.3.6 + prop-types: 15.8.1 + react: 19.3.0 + react-clientside-effect: 1.2.8(react@19.3.0) + use-callback-ref: 1.3.3(@types/react@19.3.0)(react@19.3.0) + use-sidecar: 1.1.3(@types/react@19.3.0)(react@19.3.0) + optionalDependencies: + '@types/react': 19.3.0 + + react-i18next@13.5.0(i18next@23.4.6)(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + '@babel/runtime': 7.29.10 + html-parse-stringify: 3.1.0 + i18next: 23.4.6 + react: 19.3.0 + optionalDependencies: + react-dom: 19.3.0(react@19.3.0) + + react-international-phone@4.5.0(react@19.3.0): + dependencies: + react: 19.3.0 + react-is@16.13.1: {} + react-transition-group@4.4.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0): + dependencies: + '@babel/runtime': 7.29.10 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + react@19.3.0: {} + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@5.1.1: {} + + real-require@0.1.0: {} + + real-require@0.2.0: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.9 @@ -4954,10 +11227,23 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + resolve-alpn@1.2.1: {} + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} + resolve@1.22.13: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.17.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + resolve@2.0.0-next.7: dependencies: es-errors: 1.3.0 @@ -4967,6 +11253,10 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + reusify@1.1.0: {} rolldown@1.2.13: @@ -4994,6 +11284,19 @@ snapshots: rou3@1.0.0: {} + rpc-websockets@9.3.9: + dependencies: + '@swc/helpers': 0.5.23 + '@types/uuid': 10.0.0 + '@types/ws': 8.18.2 + buffer: 6.0.3 + eventemitter3: 5.0.1 + uuid: 14.0.3 + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -5006,6 +11309,8 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 + safe-buffer@5.2.1: {} + safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -5017,12 +11322,18 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 + safe-stable-stringify@2.5.0: {} + scheduler@0.28.0: {} semver@6.3.1: {} + semver@7.7.2: {} + semver@7.8.5: {} + set-blocking@2.0.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -5045,6 +11356,40 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.1.2 + sha256-uint8array@0.10.7: {} + + sharp@0.35.0: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.0 + '@img/sharp-darwin-x64': 0.35.0 + '@img/sharp-freebsd-wasm32': 0.35.0 + '@img/sharp-libvips-darwin-arm64': 1.3.0 + '@img/sharp-libvips-darwin-x64': 1.3.0 + '@img/sharp-libvips-linux-arm': 1.3.0 + '@img/sharp-libvips-linux-arm64': 1.3.0 + '@img/sharp-libvips-linux-ppc64': 1.3.0 + '@img/sharp-libvips-linux-riscv64': 1.3.0 + '@img/sharp-libvips-linux-s390x': 1.3.0 + '@img/sharp-libvips-linux-x64': 1.3.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.0 + '@img/sharp-libvips-linuxmusl-x64': 1.3.0 + '@img/sharp-linux-arm': 0.35.0 + '@img/sharp-linux-arm64': 0.35.0 + '@img/sharp-linux-ppc64': 0.35.0 + '@img/sharp-linux-riscv64': 0.35.0 + '@img/sharp-linux-s390x': 0.35.0 + '@img/sharp-linux-x64': 0.35.0 + '@img/sharp-linuxmusl-arm64': 0.35.0 + '@img/sharp-linuxmusl-x64': 0.35.0 + '@img/sharp-webcontainers-wasm32': 0.35.0 + '@img/sharp-win32-arm64': 0.35.0 + '@img/sharp-win32-ia32': 0.35.0 + '@img/sharp-win32-x64': 0.35.0 + sharp@0.35.5(@types/node@24.19.0): dependencies: '@img/colour': 1.1.0 @@ -5115,8 +11460,26 @@ snapshots: siginfo@2.0.0: {} + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + slow-redact@0.3.2: {} + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + sonic-boom@4.2.1: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.2: {} + source-map@0.5.7: {} + + split-on-first@1.1.0: {} + split2@4.2.0: {} srvx@1.0.5: {} @@ -5132,6 +11495,22 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 + + stream-shift@1.0.3: {} + + strict-uri-encode@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.9 @@ -5183,6 +11562,14 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.2 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-bom@3.0.0: {} strip-json-comments@3.1.1: {} @@ -5194,12 +11581,30 @@ snapshots: optionalDependencies: '@babel/core': 7.29.7 + stylis@4.2.0: {} + + superstruct@2.0.2: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} + text-encoding-utf-8@1.0.2: {} + + text-encoding@0.7.0: {} + + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + + thread-stream@3.2.0: + dependencies: + real-require: 0.2.0 + + tiny-warning@1.0.3: {} + tinybench@2.9.0: {} tinyexec@1.3.1: {} @@ -5211,10 +11616,20 @@ snapshots: tinyrainbow@3.2.0: {} + tldts-core@6.1.86: {} + + tldts@6.0.16: + dependencies: + tldts-core: 6.1.86 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + to-utf8@0.0.1: {} + + toposort@2.0.2: {} + tr46@0.0.3: {} ts-api-utils@2.5.0(typescript@6.0.3): @@ -5228,8 +11643,14 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@1.14.1: {} + + tslib@2.4.1: {} + tslib@2.8.1: {} + tweetnacl@1.0.3: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -5279,6 +11700,14 @@ snapshots: typescript@6.0.3: {} + ufo@1.6.4: {} + + uint8arrays@3.1.1: + dependencies: + multiformats: 9.9.0 + + ulid@2.4.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -5286,6 +11715,8 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + uncrypto@0.1.3: {} + undici-types@5.26.5: {} undici-types@7.24.6: {} @@ -5325,6 +11756,20 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 + unstorage@1.17.6(db0@0.4.1)(idb-keyval@6.3.0): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.3 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + db0: 0.4.1 + idb-keyval: 6.3.0 + unstorage@2.0.0-alpha.11: {} update-browserslist-db@1.3.4(browserslist@4.29.3): @@ -5337,6 +11782,130 @@ snapshots: dependencies: punycode: 2.3.1 + url@0.11.0: + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + + use-callback-ref@1.3.3(@types/react@19.3.0)(react@19.3.0): + dependencies: + react: 19.3.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.3.0 + + use-sidecar@1.1.3(@types/react@19.3.0)(react@19.3.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.3.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.3.0 + + utf-8-validate@6.0.6: + dependencies: + node-gyp-build: 4.8.4 + optional: true + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.2 + is-typed-array: 1.1.15 + which-typed-array: 1.1.24 + + uuid@11.1.0: {} + + uuid@11.1.1: {} + + uuid@14.0.3: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + valibot@1.5.0(typescript@6.0.3): + optionalDependencies: + typescript: 6.0.3 + + valtio@2.1.7(@types/react@19.3.0)(react@19.3.0): + dependencies: + proxy-compare: 3.0.1 + optionalDependencies: + '@types/react': 19.3.0 + react: 19.3.0 + + viem@2.31.0(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@6.0.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.2(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + ox: 0.7.1(typescript@6.0.3)(zod@3.22.4) + ws: 8.18.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.46.3(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + ox: 0.12.4(typescript@6.0.3)(zod@3.22.4) + ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@3.22.4) + isows: 1.0.7(ws@8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + ox: 0.14.56(typescript@6.0.3)(zod@3.22.4) + ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.57.7(bufferutil@4.1.0)(typescript@6.0.3)(utf-8-validate@6.0.6)(zod@4.6.7): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@4.6.7) + isows: 1.0.7(ws@8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + ox: 0.14.56(typescript@6.0.3)(zod@4.6.7) + ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite@8.3.3(@types/node@24.19.0)(esbuild@0.28.2): dependencies: lightningcss: 1.33.0 @@ -5377,6 +11946,8 @@ snapshots: transitivePeerDependencies: - msw + void-elements@3.1.0: {} + web-streams-polyfill@4.0.0-beta.3: {} webidl-conversions@3.0.1: {} @@ -5417,6 +11988,8 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 + which-module@2.0.1: {} + which-typed-array@1.1.24: dependencies: available-typed-arrays: 1.0.7 @@ -5438,14 +12011,87 @@ snapshots: word-wrap@1.2.5: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + + ws@8.18.2(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + + ws@8.18.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + + ws@8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + + ws@8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + xtend@4.0.2: {} + y18n@4.0.3: {} + yallist@3.1.1: {} + yaml@1.10.3: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yocto-queue@0.1.0: {} + yup@0.32.11: + dependencies: + '@babel/runtime': 7.29.10 + '@types/lodash': 4.17.27 + lodash: 4.18.1 + lodash-es: 4.18.1 + nanoclone: 0.2.1 + property-expr: 2.0.6 + toposort: 2.0.2 + zod-validation-error@4.0.2(zod@4.6.7): dependencies: zod: 4.6.7 + zod@3.22.4: {} + zod@4.6.7: {} + + zustand@5.0.3(@types/react@19.3.0)(react@19.3.0): + optionalDependencies: + '@types/react': 19.3.0 + react: 19.3.0 diff --git a/proxy.ts b/proxy.ts new file mode 100644 index 0000000..309492c --- /dev/null +++ b/proxy.ts @@ -0,0 +1,17 @@ +import { routeAuth } from "eve/channels/auth"; +import { NextResponse } from "next/server"; +import { operatorAuth } from "./server/operator-auth"; + +// No other site may frame these pages, so a hostile page cannot trick the operator into a click. +const FRAME_HEADERS = { "Content-Security-Policy": "frame-ancestors 'none'", "X-Frame-Options": "DENY" }; + +// The Crossmint setup page is for the operator only. Asking here lets the browser show its HTTP +// Basic prompt; the page and every action check again. +export async function proxy(request: Request) { + const auth = await routeAuth(request, [operatorAuth]); + const response = auth instanceof Response ? auth : NextResponse.next(); + for (const [name, value] of Object.entries(FRAME_HEADERS)) response.headers.set(name, value); + return response; +} + +export const config = { matcher: ["/crossmint/:path*"] }; diff --git a/scripts/crossmint-operator-jwt.mjs b/scripts/crossmint-operator-jwt.mjs new file mode 100644 index 0000000..6dbc569 --- /dev/null +++ b/scripts/crossmint-operator-jwt.mjs @@ -0,0 +1,15 @@ +import { operatorJwt, parseRsaPrivateKey, JWT_TTL_SECONDS } from "../server/crossmint/operator-jwt.ts"; + +// Prints a ten-minute operator JWT for Crossmint Agent Cards, signed with CROSSMINT_JWT_PRIVATE_KEY. +// Use it to sign in to a card setup app, or to call the order intent API by hand. Treat it like a +// password until it expires: it can create order intents and mint cards for the operator. +// Usage: pnpm crossmint:operator-jwt +const projectId = process.env.CROSSMINT_PROJECT_ID?.trim(); +const userId = process.env.CROSSMINT_USER_ID?.trim(); +const configured = process.env.CROSSMINT_JWT_PRIVATE_KEY?.trim(); +if (!projectId || !userId || !configured) throw new Error("Set CROSSMINT_PROJECT_ID, CROSSMINT_USER_ID, and CROSSMINT_JWT_PRIVATE_KEY."); +const privateKey = parseRsaPrivateKey(configured); +if (!privateKey) throw new Error("CROSSMINT_JWT_PRIVATE_KEY must be a base64-encoded PEM RSA private key of at least 2048 bits."); + +console.log(operatorJwt({ projectId, userId, privateKey })); +console.error(`Valid for ${JWT_TTL_SECONDS / 60} minutes.`); diff --git a/scripts/demo-crossmint.mjs b/scripts/demo-crossmint.mjs new file mode 100644 index 0000000..7589d94 --- /dev/null +++ b/scripts/demo-crossmint.mjs @@ -0,0 +1,102 @@ +import { readFileSync } from "node:fs"; +import { parseEnv } from "node:util"; + +// Opt-in: starts one real Crossmint Agent Checkout and watches it. Answers nothing, so it stops at +// the first question or the first terminal state. Crossmint bills the run. Cancel it in the console. +// Usage: node scripts/demo-crossmint.mjs [currency] +const preset = new Set(Object.keys(process.env)); +for (const file of [".env", ".env.local"]) { + let text; + try { text = readFileSync(file, "utf8"); } catch { continue; } + for (const [key, value] of Object.entries(parseEnv(text))) if (!preset.has(key)) process.env[key] = value; +} + +const [startUrl, amount, currency = "USD"] = process.argv.slice(2); +if (!startUrl || !amount) throw new Error("Usage: node scripts/demo-crossmint.mjs [currency]"); +if (!URL.canParse(startUrl) || new URL(startUrl).protocol !== "https:") throw new Error("The product URL must be https."); +if (!/^(?:[1-9]\d{0,14}(?:\.\d{1,2})?|0\.(?=\d*[1-9])\d{1,2})$/.test(amount)) throw new Error("The cap must be a decimal such as 20.00."); +if (!/^[A-Z]{3}$/.test(currency)) throw new Error("The currency must be an ISO 4217 code such as USD."); +const apiKey = process.env.CROSSMINT_SERVER_API_KEY?.trim(); +const userId = process.env.CROSSMINT_USER_ID?.trim(); +if (!apiKey?.startsWith("sk_") || !userId) throw new Error("Set CROSSMINT_SERVER_API_KEY (sk_...) and CROSSMINT_USER_ID."); +const baseUrl = (process.env.CROSSMINT_API_BASE_URL?.trim() || "https://www.crossmint.com/api/unstable").replace(/\/$/, ""); +const buyerProfileId = process.env.CROSSMINT_BUYER_PROFILE_ID?.trim(); +const headers = { "X-API-KEY": apiKey, "x-crossmint-user-id": userId, "Content-Type": "application/json" }; + +// Errors never include the response body: it can echo the request, the key prefix, or merchant data. +async function call(path, init = {}) { + const response = await fetch(`${baseUrl}${path}`, { ...init, headers, redirect: "error", signal: AbortSignal.timeout(20_000) }); + if (!response.ok) throw new Error(`Crossmint returned HTTP ${response.status} for ${init.method ?? "GET"} ${path}.`); + return response.json(); +} + +const describe = (run) => { + const action = run.requiredAction?.request; + if (!action) return ""; + const { interaction } = action; + if (interaction.kind === "form") { + const fields = interaction.fields.map((field) => `${field.key} (${field.handling}, ${field.input.kind})`).join(", "); + return `\n question: ${action.question}\n fields: ${fields}`; + } + if (interaction.kind === "payment") { + return `\n question: ${action.question}\n payment: ${interaction.method} ${interaction.amount.kind} ${interaction.amount.value} ${interaction.amount.currency} at ${interaction.merchant?.url ?? "unknown merchant"}`; + } + return `\n question: ${action.question}`; +}; + +const { runId } = await call("/agent-checkouts", { + method: "POST", + body: JSON.stringify({ + request: { startUrl, task: `Go to the checkout for this product with standard delivery and pay by card.` }, + constraints: { maxCost: { amount, currency } }, + ...(buyerProfileId ? { buyerProfileId } : {}), + }), +}); +console.log(`run ${runId}`); +console.log(`console https://www.crossmint.com/console (Agent Checkouts, search for the run id)`); + +// The same fixed stage phrases Bell reports, from the activity kinds in the run's messages. +const STAGES = [ + [["apply_payment"], "Applying the payment"], + [["apply_buyer_information"], "Filling in the delivery details"], + [["create_checkout"], "Starting the store's checkout"], + [["call_webmcp_tool"], "Using the store's checkout tools"], + [["lookup_product", "search_catalog"], "Finding the product"], + [["navigate", "read_playbook"], "Opening the store"], +]; +async function stage() { + const { data = [] } = await call(`/agent-checkouts/${encodeURIComponent(runId)}/messages?limit=100`); + const activities = data + .filter((message) => message.role === "assistant") + .sort((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt)) + .flatMap((message) => message.parts ?? []) + .filter((part) => part.type === "activity"); + if (!activities.length) return ""; + const kinds = new Set((activities.at(-1).operations ?? []).map((operation) => operation.kind)); + return STAGES.find(([candidates]) => candidates.some((kind) => kinds.has(kind)))?.[1] ?? "Working through the store's checkout"; +} + +const deadline = Date.now() + 10 * 60_000; +let last = ""; +let lastStage = ""; +let run; +do { + run = await call(`/agent-checkouts/${encodeURIComponent(runId)}`); + const line = `${run.status} (revision ${run.revision})${describe(run)}`; + if (line !== last) console.log(`${new Date().toISOString().slice(11, 19)} ${line}`); + last = line; + if (run.status === "running") { + const current = await stage().catch(() => lastStage); + if (current && current !== lastStage) console.log(`${new Date().toISOString().slice(11, 19)} ${current}`); + lastStage = current; + } + if (run.status === "awaiting_input" || ["succeeded", "failed", "cancelled", "blocked"].includes(run.status)) break; + await new Promise((resolve) => setTimeout(resolve, 2_000)); +} while (Date.now() < deadline); + +if (run.status === "awaiting_input") console.log("Stopped at the first question. Nothing was answered and nothing was bought. Cancel the run in the console when done."); +else if (run.status === "blocked") console.log(`Blocked with ${run.result?.code ?? "no code"}: ${run.result?.summary ?? ""}`); +else if (run.status === "failed") console.log(`Failed with reason ${run.reason ?? "unknown"}.`); +else if (run.status === "succeeded") console.log(`Succeeded: ${run.result?.summary ?? ""}`); +else if (run.status === "cancelled") console.log("Cancelled."); +else { console.log("Still running after ten minutes. Watch it in the console."); process.exitCode = 1; } diff --git a/server/browser/privacy-lock.ts b/server/browser/privacy-lock.ts index f53ca7d..8dacc90 100644 --- a/server/browser/privacy-lock.ts +++ b/server/browser/privacy-lock.ts @@ -1,11 +1,17 @@ import { AsyncLocalStorage } from "node:async_hooks"; import { Pool } from "pg"; +import { isCrossmintCardsConfigured } from "../crossmint/cards"; import { isLinkSandbox } from "../link/sandbox"; const current = new AsyncLocalStorage<() => Promise>(); const sandboxBrowsers = new Map; quarantined: boolean }>(); let pool: Pool | undefined; +/** True inside an operation that holds the browser privacy lock, so a payment can quarantine it. */ +export function hasBrowserPrivacyLock(): boolean { + return current.getStore() !== undefined; +} + export async function quarantineBrowser(): Promise { const lock = current.getStore(); if (!lock) throw new Error("Payment requires a private browser lock."); @@ -27,8 +33,8 @@ export async function withBrowserPrivacyLock(sessionId: string, operation: () return await current.run(async () => { state.quarantined = true; }, operation); } finally { release(); } } - if (!database && !process.env.LINK_CLIENT_ID?.trim()) return operation(); - if (!database && !process.env.DATABASE_URL) throw new Error("Link checkout requires DATABASE_URL."); + if (!database && !process.env.LINK_CLIENT_ID?.trim() && !isCrossmintCardsConfigured()) return operation(); + if (!database && !process.env.DATABASE_URL) throw new Error("Browser payments require DATABASE_URL."); if (!database && !pool) { pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 5, connectionTimeoutMillis: 10_000, idleTimeoutMillis: 30_000, allowExitOnIdle: true }); pool.on("error", () => console.error("Browser privacy database connection failed.")); diff --git a/server/crossmint/cards.ts b/server/crossmint/cards.ts new file mode 100644 index 0000000..b46fc83 --- /dev/null +++ b/server/crossmint/cards.ts @@ -0,0 +1,265 @@ +import { createHash } from "node:crypto"; +import { z } from "zod"; +import { compareAmounts, CrossmintRequestError, CrossmintSetupError, isCrossmintConfigured, type MaxCost } from "./client"; +import { isOperatorConfigured, operatorConfig, operatorRequest, type OperatorConfig } from "./operator"; +import { hostOf } from "./payment"; + +/** + * Crossmint Agent Cards, server side. + * + * The person approves an order intent on Bell's setup page beforehand: a saved card, an amount, a + * merchant, and an expiry. At payment time Bell reads the order intent, checks it against the payment + * the person approved in chat, and mints a one-time card on the card network's rail, Visa Intelligent + * Commerce or Mastercard Agent Pay. The card is filled into the merchant page on the server and is + * never returned. A mint spends its amount at once, even if the card is never used, so every check + * runs before it. + * API reference: https://docs.crossmint.com/api-reference/agentic-commerce/order-intents/get-order-intent + */ + +export interface CardConfig extends OperatorConfig { + /** Payment-frame origins trusted per merchant origin, such as a payment provider's card iframe. */ + checkoutOrigins: Record; +} + +/** + * Paying in Bell's own browser is opt-in. The setup keys alone only approve budgets for Agent + * Checkouts, so setting them up never adds this tool or the browser database requirement. + */ +export function isCrossmintCardsConfigured(env: Record = process.env): boolean { + return env.CROSSMINT_CARD_CHECKOUT?.trim() === "1" && isCrossmintConfigured(env) && isOperatorConfigured(env); +} + +const exactHttpsOrigin = (value: string) => { + const url = URL.parse(value); + return url?.protocol === "https:" && url.origin === value; +}; + +export function cardConfig(env: Record = process.env): CardConfig { + const base = operatorConfig(env); + const invalid = () => new CrossmintSetupError("invalid_configuration", "CROSSMINT_CHECKOUT_ORIGINS"); + let checkoutOrigins: Record; + try { + checkoutOrigins = z.record(z.string(), z.array(z.string())).parse(JSON.parse(env.CROSSMINT_CHECKOUT_ORIGINS?.trim() || "{}")); + } catch { + throw invalid(); + } + if (Object.entries(checkoutOrigins).some(([merchant, origins]) => !exactHttpsOrigin(merchant) || !origins.every(exactHttpsOrigin))) { + throw invalid(); + } + return { ...base, checkoutOrigins }; +} + +/** Fixed messages the model may see. Crossmint's own error messages are never passed on. */ +const CARD_MESSAGES = { + unauthorized: "Crossmint rejected the client key, its allowed origins, or Bell's operator token.", + order_intent_not_found: "Crossmint has no order intent with that id for this operator. Check CROSSMINT_ORDER_INTENT_ID and CROSSMINT_USER_ID.", + order_intent_inactive: "The order intent is cancelled. Ask the person to approve a new one.", + order_intent_expired: "The order intent has expired or expires within a minute. Ask the person to approve a new one.", + merchant_scope_required: "The order intent names no merchant. Ask the person to approve one for this merchant.", + merchant_mismatch: "The order intent is for a different merchant.", + currency_mismatch: "The order intent is in a different currency.", + insufficient_allowance: "The amount is more than what is left on the order intent.", + rail_pending_verification: "The card is not verified for this order intent yet. Ask the person to finish verification in the card setup.", + rail_error: "The card network turned this card down for agent payments. Ask the person to use another card.", + no_card_rail: "This card has neither a Visa Intelligent Commerce nor a Mastercard Agent Pay rail, so Bell cannot pay with it here.", + invalid_merchant: "The merchant must be an HTTPS URL or a host name.", + unsupported_amount: "The amount has more decimals than the currency allows.", + cvc_recollection_required: "Crossmint needs the card's CVC again. Ask the person to re-enter it in the card setup. No card was issued.", + payment_method_deleted: "The card behind the order intent was removed. Ask the person to save a card and approve a new order intent.", + credential_already_issued: "This payment already issued its card. Do not retry. Check the merchant page through human handoff.", + credential_unavailable: "Crossmint could not issue a card for this payment. Tell the person and do not retry.", + retry_later: "Crossmint is still issuing a card for this payment. Check the merchant page before any retry.", + unexpected_credential: "Crossmint returned a card that does not match this payment, so nothing was filled. Tell the person.", + browser_lock_unavailable: "Bell could not lock this browser for card entry, so no card was issued. Agent Cards needs LINK_SANDBOX=0 and DATABASE_URL. See docs/crossmint.md.", + card_issued_unfinished: "A one-time card was issued, but the payment did not finish. The browser is now private. Check the merchant page through human handoff and do not retry.", +} as const; + +export type CardReason = keyof typeof CARD_MESSAGES; + +export class CrossmintCardError extends Error { + constructor(readonly reason: CardReason) { + super(CARD_MESSAGES[reason]); + this.name = "CrossmintCardError"; + } +} + +/** Crossmint error codes an operator or the person has to act on. Any other code stays an HTTP status. */ +const ERROR_CODES: Readonly> = { + ORDER_INTENT_CVC_RECOLLECTION_REQUIRED: "cvc_recollection_required", + "payments:payment-method.deleted": "payment_method_deleted", + ORDER_INTENT_CREDENTIAL_ALREADY_ISSUED: "credential_already_issued", + ORDER_INTENT_AMOUNT_EXCEEDED: "insufficient_allowance", + ORDER_INTENT_EXPIRED: "order_intent_expired", + ORDER_INTENT_CANCELLED: "order_intent_inactive", + ORDER_INTENT_CREDENTIAL_UNAVAILABLE: "credential_unavailable", + ORDER_INTENT_PROVIDER_OPERATION_IN_PROGRESS: "retry_later", +}; + +export interface CardClientOptions { + config?: CardConfig; + fetch?: typeof fetch; + signal?: AbortSignal; +} + +async function errorReason(response: Response): Promise { + try { + const { code } = (await response.json()) as { code?: unknown }; + return typeof code === "string" && Object.hasOwn(ERROR_CODES, code) ? ERROR_CODES[code] : undefined; + } catch { + return undefined; + } +} + +/** One call with the client key, the operator JWT, and Bell's origin. Only fixed reasons leave it. */ +export async function cardRequest( + path: string, + init: { method: "GET" | "POST" | "PUT"; body?: unknown; idempotencyKey?: string }, + options: CardClientOptions = {}, +): Promise { + const config = options.config ?? cardConfig(); + const response = await operatorRequest(path, init, { ...options, config }); + if (!response.ok) { + const reason = await errorReason(response); + if (reason) throw new CrossmintCardError(reason); + if (response.status === 401 || response.status === 403) throw new CrossmintCardError("unauthorized"); + if (response.status === 404) throw new CrossmintCardError("order_intent_not_found"); + throw new CrossmintRequestError(response.status === 429 ? "rate_limited" : "http_error", response.status); + } + const text = await response.text().catch(() => ""); + try { + return JSON.parse(text) as unknown; + } catch { + throw new CrossmintRequestError("invalid_response", response.status); + } +} + +const railSchema = z.object({ + rail: z.string(), + provider: z.string().optional(), + status: z.string(), + credentialFormats: z.array(z.string()).optional(), +}); + +const orderIntentSchema = z.object({ + status: z.string(), + amount: z.object({ available: z.string().regex(/^\d+(?:\.\d+)?$/), currency: z.string() }), + expiresAt: z.string(), + merchant: z.object({ url: z.string() }).nullish(), + rails: z.array(railSchema), +}); + +export type OrderIntent = z.infer; +export type CardProvider = "vic" | "agentpay"; + +function orderIntentPath(config: CardConfig): string { + if (!config.orderIntentId) throw new CrossmintSetupError("missing_configuration", "CROSSMINT_ORDER_INTENT_ID"); + return `/order-intents/${encodeURIComponent(config.orderIntentId)}`; +} + +/** Read the operator's order intent. Only refusal reasons derived from it reach the model. */ +export async function getOrderIntent(options: CardClientOptions = {}): Promise { + const config = options.config ?? cardConfig(); + const parsed = orderIntentSchema.safeParse(await cardRequest(orderIntentPath(config), { method: "GET" }, { ...options, config })); + if (!parsed.success) throw new CrossmintRequestError("invalid_response"); + return parsed.data; +} + +/** HTTPS origin of the merchant the model named, from a URL or a bare host. */ +export function merchantOrigin(merchant: string): string { + const url = URL.parse(merchant.includes("://") ? merchant : `https://${merchant}`); + if (!url || url.protocol !== "https:" || url.username || url.password) throw new CrossmintCardError("invalid_merchant"); + return url.origin; +} + +/** The merchant origin and any payment-frame origins the operator trusts for it. */ +export function paymentOrigins(config: CardConfig, origin: string): string[] { + return [...new Set([origin, ...(config.checkoutOrigins[origin] ?? [])])]; +} + +/** The order intent must be live, scoped to this merchant, in this currency, with room for the amount and a verified card rail. */ +export function assertCardPayment(intent: OrderIntent, payment: MaxCost & { merchant: string }, now = Date.now()): { provider: CardProvider } { + if (intent.status === "expired") throw new CrossmintCardError("order_intent_expired"); + if (intent.status !== "active") throw new CrossmintCardError("order_intent_inactive"); + const expiresAt = Date.parse(intent.expiresAt); + if (!Number.isFinite(expiresAt) || expiresAt - now < 60_000) throw new CrossmintCardError("order_intent_expired"); + if (!intent.merchant?.url) throw new CrossmintCardError("merchant_scope_required"); + const host = hostOf(intent.merchant.url); + if (!host || host !== hostOf(payment.merchant)) throw new CrossmintCardError("merchant_mismatch"); + if (intent.amount.currency.toUpperCase() !== payment.currency) throw new CrossmintCardError("currency_mismatch"); + if (compareAmounts(intent.amount.available, payment.amount) < 0) throw new CrossmintCardError("insufficient_allowance"); + + const rails = intent.rails.filter( + (rail): rail is typeof rail & { provider: CardProvider } => rail.rail === "agentic-token" && (rail.provider === "vic" || rail.provider === "agentpay"), + ); + const active = rails.find((rail) => rail.status === "active" && rail.credentialFormats?.includes("card")); + if (active) return { provider: active.provider }; + if (rails.some((rail) => rail.status === "pending_verification")) throw new CrossmintCardError("rail_pending_verification"); + if (rails.some((rail) => rail.status === "error")) throw new CrossmintCardError("rail_error"); + throw new CrossmintCardError("no_card_rail"); +} + +/** Stable per tool call, so a re-run of the same call never mints a second card. */ +export function idempotencyKey(sessionId: string, callId: string): string { + return `bell-card-${createHash("sha256").update(`${sessionId}:${callId}`).digest("hex")}`; +} + +/** The amount in the currency's smallest unit, for the browser fill's input record. */ +export function checkoutAmount(amount: string, currency: string): number { + const digits = new Intl.NumberFormat("en", { style: "currency", currency }).resolvedOptions().maximumFractionDigits ?? 2; + const [whole, fraction = ""] = amount.split("."); + const minor = Number(whole + fraction.padEnd(digits, "0")); + if (fraction.length > digits || !Number.isSafeInteger(minor) || minor <= 0) throw new CrossmintCardError("unsupported_amount"); + return minor; +} + +const issuedSchema = z.object({ + rail: z.literal("agentic-token"), + amount: z.object({ value: z.string().regex(/^\d+(?:\.\d+)?$/), currency: z.string() }), + expiresAt: z.string().optional(), + credential: z.object({ + format: z.literal("card"), + value: z.object({ + number: z.string().regex(/^\d{12,19}$/), + expirationMonth: z.number().int().min(1).max(12), + expirationYear: z.number().int().min(0), + cvc: z.string().regex(/^\d{3,4}$/), + }), + }), +}); + +/** The shape the browser fill expects. It lives only inside the fill operation. */ +export interface CardCredential { + card: { number: string; cvc: string; exp_month: number; exp_year: number; valid_until?: string }; +} + +export function projectCard(raw: unknown, requested: MaxCost): CardCredential { + const parsed = issuedSchema.safeParse(raw); + if (!parsed.success) throw new CrossmintCardError("unexpected_credential"); + const { amount, expiresAt, credential } = parsed.data; + if (amount.currency.toUpperCase() !== requested.currency || compareAmounts(amount.value, requested.amount) !== 0) { + throw new CrossmintCardError("unexpected_credential"); + } + const { number, cvc, expirationMonth, expirationYear } = credential.value; + return { + card: { + number, + cvc, + exp_month: expirationMonth, + exp_year: expirationYear < 100 ? 2000 + expirationYear : expirationYear, + ...(expiresAt ? { valid_until: expiresAt } : {}), + }, + }; +} + +/** Mint a one-time card for exactly this amount on the order intent's network rail. */ +export async function mintCard(provider: CardProvider, amount: MaxCost, key: string, options: CardClientOptions = {}): Promise { + const config = options.config ?? cardConfig(); + const body = { + rail: "agentic-token", + provider, + amount: { value: amount.amount, currency: amount.currency }, + credential: { format: "card" }, + }; + const raw = await cardRequest(`${orderIntentPath(config)}/credentials`, { method: "POST", body, idempotencyKey: key }, { ...options, config }); + return projectCard(raw, amount); +} diff --git a/server/crossmint/client.ts b/server/crossmint/client.ts new file mode 100644 index 0000000..6cf5c63 --- /dev/null +++ b/server/crossmint/client.ts @@ -0,0 +1,591 @@ +import { randomUUID } from "node:crypto"; + +/** + * Crossmint Agent Checkouts, server side. + * + * Crossmint runs the checkout at any store and exposes it as a run with status snapshots. Bell + * holds the API key, the buyer id, the optional buyer profile, and the order intent on the server. + * The model sees a projection of each snapshot and nothing else. + * API reference: https://docs.crossmint.com/api-reference/agent-checkouts + */ + +export class CrossmintSetupError extends Error { + constructor( + readonly reason: "missing_configuration" | "invalid_configuration", + readonly setting: string, + ) { + super(`Check ${setting} in the server configuration.`); + this.name = "CrossmintSetupError"; + } +} + +/** Fixed messages. Provider bodies can echo the request, the key prefix, or merchant data. */ +const REQUEST_MESSAGES = { + unauthorized: "Crossmint rejected the API key or its scopes.", + not_found: "Crossmint has no checkout with that id for this buyer.", + rate_limited: "Crossmint rate limited the request. Retry shortly.", + transport: "Crossmint request failed. Check connectivity and retry.", + invalid_response: "Crossmint returned an unexpected response.", +}; + +export type CrossmintRequestReason = keyof typeof REQUEST_MESSAGES | "http_error"; + +export class CrossmintRequestError extends Error { + constructor( + readonly reason: CrossmintRequestReason, + readonly status?: number, + ) { + super(reason === "http_error" ? `Crossmint returned HTTP ${status}.` : REQUEST_MESSAGES[reason]); + this.name = "CrossmintRequestError"; + } +} + +/** A request the operator's policy refuses before it reaches Crossmint. */ +export class CrossmintPolicyError extends Error { + constructor( + readonly reason: "merchant_not_allowed" | "cap_exceeded" | "currency_mismatch", + message: string, + ) { + super(message); + this.name = "CrossmintPolicyError"; + } +} + +export interface MaxCost { + amount: string; + currency: string; +} + +export interface CrossmintConfig { + apiKey: string; + userId: string; + baseUrl: string; + /** Optional saved buyer profile (name, email, shipping) so checkouts ask fewer questions. */ + buyerProfileId?: string; + /** Optional ceiling on any single checkout's maxCost, enforced before the request is created. */ + maxCost?: MaxCost; + /** Optional exact HTTPS origins a checkout may start from. Empty allows any merchant. */ + allowedMerchants: string[]; + /** The operator's approved order intent, used to pay. Never exposed to the model. */ + orderIntentId?: string; +} + +export const DEFAULT_BASE_URL = "https://www.crossmint.com/api/unstable"; + +/** Crossmint's amount pattern, capped at two decimals. No zero, no leading zeros. */ +export const AMOUNT = /^(?:[1-9]\d{0,14}(?:\.\d{1,2})?|0\.(?=\d*[1-9])\d{1,2})$/; +export const CURRENCY = /^[A-Z]{3}$/; + +export function isCrossmintConfigured(env: Record = process.env): boolean { + return Boolean(env.CROSSMINT_SERVER_API_KEY?.trim() && env.CROSSMINT_USER_ID?.trim()); +} + +export function crossmintConfig(env: Record = process.env): CrossmintConfig { + const required = (name: string) => { + const value = env[name]?.trim(); + if (!value) throw new CrossmintSetupError("missing_configuration", name); + return value; + }; + const invalid = (name: string) => new CrossmintSetupError("invalid_configuration", name); + const httpsUrl = (value: string, name: string) => { + const url = URL.parse(value); + if (!url || url.protocol !== "https:" || url.username || url.password) throw invalid(name); + return url; + }; + + const apiKey = required("CROSSMINT_SERVER_API_KEY"); + if (!apiKey.startsWith("sk_")) throw invalid("CROSSMINT_SERVER_API_KEY"); + const userId = required("CROSSMINT_USER_ID"); + const base = httpsUrl(env.CROSSMINT_API_BASE_URL?.trim() || DEFAULT_BASE_URL, "CROSSMINT_API_BASE_URL"); + if (base.search || base.hash) throw invalid("CROSSMINT_API_BASE_URL"); + + let maxCost: MaxCost | undefined; + const cap = env.CROSSMINT_MAX_COST?.trim(); + if (cap) { + const [amount = "", currency = ""] = cap.split(/\s+/); + if (!AMOUNT.test(amount) || !CURRENCY.test(currency)) throw invalid("CROSSMINT_MAX_COST"); + maxCost = { amount, currency }; + } + + const allowedMerchants = env.CROSSMINT_ALLOWED_MERCHANTS?.split(",").map((value) => value.trim()).filter(Boolean) ?? []; + for (const origin of allowedMerchants) { + if (httpsUrl(origin, "CROSSMINT_ALLOWED_MERCHANTS").origin !== origin) throw invalid("CROSSMINT_ALLOWED_MERCHANTS"); + } + + return { + apiKey, + userId, + baseUrl: base.href.replace(/\/$/, ""), + buyerProfileId: env.CROSSMINT_BUYER_PROFILE_ID?.trim() || undefined, + maxCost, + allowedMerchants, + orderIntentId: env.CROSSMINT_ORDER_INTENT_ID?.trim() || undefined, + }; +} + +/** Compare two decimal strings at Crossmint's six-decimal precision. Returns -1, 0, or 1. */ +export function compareAmounts(a: string, b: string): number { + const scale = (value: string) => { + const [whole, fraction = ""] = value.split("."); + return BigInt(whole + fraction.padEnd(6, "0").slice(0, 6)); + }; + const left = scale(a); + const right = scale(b); + return left < right ? -1 : left > right ? 1 : 0; +} + +/** Enforce the operator's merchant allowlist and spending ceiling before anything is created. */ +export function assertCheckoutPolicy(startUrl: string, maxCost: MaxCost, config: CrossmintConfig): void { + if (config.allowedMerchants.length) { + const url = URL.parse(startUrl); + if (!url || url.protocol !== "https:" || url.username || url.password || !config.allowedMerchants.includes(url.origin)) { + throw new CrossmintPolicyError("merchant_not_allowed", "This merchant is not in CROSSMINT_ALLOWED_MERCHANTS."); + } + } + if (config.maxCost) { + if (maxCost.currency !== config.maxCost.currency) { + throw new CrossmintPolicyError("currency_mismatch", `Checkouts are limited to ${config.maxCost.currency} by CROSSMINT_MAX_COST.`); + } + if (compareAmounts(maxCost.amount, config.maxCost.amount) > 0) { + throw new CrossmintPolicyError("cap_exceeded", `The spending cap exceeds the operator ceiling of ${config.maxCost.amount} ${config.maxCost.currency}.`); + } + } +} + +export interface CreateCheckoutInput { + startUrl: string; + task: string; + maxCost: MaxCost; + merchantGuidance?: string; + countryCode?: string; +} + +export type CheckoutStatus = "queued" | "running" | "awaiting_input" | "succeeded" | "failed" | "cancelled" | "blocked"; + +const STATUSES: ReadonlySet = new Set(["queued", "running", "awaiting_input", "succeeded", "failed", "cancelled", "blocked"]); + +export const TERMINAL_STATUSES: ReadonlySet = new Set(["succeeded", "failed", "cancelled", "blocked"]); + +/** Model-safe view of a form field. `protected` fields cannot be answered through the model. */ +export interface CheckoutFormField { + key: string; + label: string; + required: boolean; + handling: "standard" | "protected"; + /** Crossmint's input kind: text, multiline, boolean, choice, integer, or number. */ + kind: string; + /** For a choice field, the values the model may answer with. Placeholder and disabled options are left out. */ + options?: { value: string; label: string }[]; + selection?: "one" | "many"; +} + +export interface CheckoutAmount { + kind: "exact" | "maximum"; + value: string; + currency: string; +} + +export interface CheckoutMerchant { + name?: string; + url?: string; + countryCode?: string; +} + +export type CheckoutInteraction = + | { kind: "form"; fields: CheckoutFormField[] } + | { kind: "payment"; method: string; amount: CheckoutAmount; merchant: CheckoutMerchant } + | { kind: "unsupported" }; + +export interface CheckoutRequiredAction { + requestId: string; + question: string; + expiresAt?: string; + interaction: CheckoutInteraction; +} + +/** The projection returned to the model. Browser URLs, the echoed input, and unknown fields are dropped. */ +export interface CheckoutSnapshot { + runId: string; + status: CheckoutStatus; + revision: number; + requiredAction: CheckoutRequiredAction | null; + result: { + outcome?: string; + summary?: string; + code?: string; + purchase?: { kind: string; receipt?: { total?: MaxCost; merchantOrderId?: string } }; + } | null; + failureReason: string | null; + /** While the run works, what Crossmint is doing. Only polls that ask for progress fill it. */ + progress?: CheckoutProgress; +} + +/** + * What a running checkout is doing, for a short update to the person: a fixed phrase chosen from + * Crossmint's activity kinds. Crossmint's own progress text is never passed on. It can name the + * buyer while the profile is applied, and it is written while reading merchant pages. + */ +export interface CheckoutProgress { + stage: string; +} + +export interface CrossmintClientOptions { + config?: CrossmintConfig; + fetch?: typeof fetch; + signal?: AbortSignal; +} + +const REQUEST_TIMEOUT_MS = 20_000; + +async function request(path: string, init: { method: "GET" | "POST"; body?: unknown }, options: CrossmintClientOptions): Promise { + const config = options.config ?? crossmintConfig(); + const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS); + const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout; + signal.throwIfAborted(); + let response: Response; + try { + response = await (options.fetch ?? fetch)(`${config.baseUrl}${path}`, { + method: init.method, + headers: { + "X-API-KEY": config.apiKey, + "x-crossmint-user-id": config.userId, + ...(init.body !== undefined ? { "Content-Type": "application/json" } : {}), + }, + body: init.body !== undefined ? JSON.stringify(init.body) : undefined, + redirect: "error", + signal, + }); + } catch { + options.signal?.throwIfAborted(); + throw new CrossmintRequestError("transport"); + } + if (!response.ok) { + const reason: CrossmintRequestReason = + response.status === 401 || response.status === 403 ? "unauthorized" + : response.status === 404 ? "not_found" + : response.status === 429 ? "rate_limited" + : "http_error"; + throw new CrossmintRequestError(reason, response.status); + } + const text = await response.text().catch(() => ""); + if (!text.trim()) return null; + try { + return JSON.parse(text) as unknown; + } catch { + throw new CrossmintRequestError("invalid_response", response.status); + } +} + +type Json = Record; + +const record = (value: unknown): Json => (typeof value === "object" && value !== null && !Array.isArray(value) ? (value as Json) : {}); +const string = (value: unknown): string | undefined => (typeof value === "string" ? value : undefined); +const present = (value: T): Partial => + Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined)) as Partial; + +function projectField(raw: unknown): CheckoutFormField | undefined { + const field = record(raw); + const key = string(field.key); + if (!key) return undefined; + const input = record(field.input); + const selectionKind = string(record(input.selection).kind); + const selection = selectionKind === "one" || selectionKind === "many" ? selectionKind : undefined; + const options = Array.isArray(input.options) + ? input.options.flatMap((option) => { + const { value, label, placeholder, disabled } = record(option); + const v = string(value); + return v === undefined || placeholder === true || disabled === true ? [] : [{ value: v, label: string(label) ?? v }]; + }) + : undefined; + return { + key, + label: string(field.label) ?? key, + required: field.required === true, + handling: field.handling === "protected" ? "protected" : "standard", + kind: string(input.kind) ?? "text", + ...(options ? { options } : {}), + ...(selection ? { selection } : {}), + }; +} + +function projectInteraction(raw: unknown): CheckoutInteraction { + const value = record(raw); + if (value.kind === "form" && Array.isArray(value.fields)) { + return { kind: "form", fields: value.fields.flatMap((field) => projectField(field) ?? []) }; + } + if (value.kind === "payment") { + const amount = record(value.amount); + const merchant = record(value.merchant); + return { + kind: "payment", + method: string(value.method) ?? "unknown", + amount: { kind: amount.kind === "maximum" ? "maximum" : "exact", value: string(amount.value) ?? "", currency: string(amount.currency) ?? "" }, + merchant: present({ name: string(merchant.name), url: string(merchant.url), countryCode: string(merchant.countryCode) }), + }; + } + return { kind: "unsupported" }; +} + +/** Project a raw snapshot to the fields the model may see. Anything unlisted is discarded. */ +export function projectCheckout(raw: unknown): CheckoutSnapshot { + const run = record(raw); + const runId = string(run.runId); + const status = string(run.status); + if (!runId || !status || !STATUSES.has(status)) throw new CrossmintRequestError("invalid_response"); + + let requiredAction: CheckoutRequiredAction | null = null; + const action = record(run.requiredAction); + const requestId = string(action.requestId); + if (status === "awaiting_input" && requestId) { + const req = record(action.request); + requiredAction = { + requestId, + question: string(req.question) ?? "", + ...present({ expiresAt: string(req.expiresAt) }), + interaction: projectInteraction(req.interaction), + }; + } + + let result: CheckoutSnapshot["result"] = null; + if (run.result !== undefined && run.result !== null) { + const raw = record(run.result); + const purchase = record(raw.purchase); + const receipt = record(purchase.receipt); + const total = record(receipt.total); + const kind = string(purchase.kind); + result = present({ + outcome: string(raw.outcome), + summary: string(raw.summary), + code: string(raw.code), + purchase: kind + ? { + kind, + ...(purchase.receipt !== undefined + ? { + receipt: present({ + total: string(total.amount) && string(total.currency) ? { amount: total.amount as string, currency: total.currency as string } : undefined, + merchantOrderId: string(receipt.merchantOrderId), + }), + } + : {}), + } + : undefined, + }); + } + + return { + runId, + status: status as CheckoutStatus, + revision: typeof run.revision === "number" ? run.revision : 0, + requiredAction, + result, + failureReason: status === "failed" ? (string(run.reason) ?? "unknown") : null, + }; +} + +export async function createCheckout(input: CreateCheckoutInput, options: CrossmintClientOptions = {}): Promise<{ runId: string }> { + const config = options.config ?? crossmintConfig(); + assertCheckoutPolicy(input.startUrl, input.maxCost, config); + const body = { + request: { startUrl: input.startUrl, task: input.task }, + constraints: { maxCost: input.maxCost }, + ...present({ + buyerProfileId: config.buyerProfileId, + merchantGuidance: input.merchantGuidance, + browser: input.countryCode ? { location: { type: "country", countryCode: input.countryCode } } : undefined, + }), + }; + const runId = string(record(await request("/agent-checkouts", { method: "POST", body }, { ...options, config })).runId); + if (!runId) throw new CrossmintRequestError("invalid_response"); + return { runId }; +} + +export async function getCheckout(runId: string, options: CrossmintClientOptions = {}): Promise { + return projectCheckout(await request(`/agent-checkouts/${encodeURIComponent(runId)}`, { method: "GET" }, options)); +} + +export type FormAnswer = string | number | boolean | string[]; + +/** One `input_response` part per message, with a fresh message id. */ +async function respond(runId: string, part: Json, options: CrossmintClientOptions): Promise { + await request( + `/agent-checkouts/${encodeURIComponent(runId)}/messages`, + { method: "POST", body: { id: `bell_${randomUUID()}`, parts: [{ type: "input_response", ...part }] } }, + options, + ); +} + +export function answerForm(runId: string, requestId: string, answers: Record, options: CrossmintClientOptions = {}): Promise { + return respond(runId, { requestId, action: "submit", response: { kind: "form", answers } }, options); +} + +/** Pay with the operator's order intent. The id is read from configuration and never returned. */ +export async function payWithOrderIntent(runId: string, requestId: string, options: CrossmintClientOptions = {}): Promise { + const config = options.config ?? crossmintConfig(); + if (!config.orderIntentId) throw new CrossmintSetupError("missing_configuration", "CROSSMINT_ORDER_INTENT_ID"); + await respond(runId, { requestId, action: "submit", response: { kind: "payment", orderIntentId: config.orderIntentId } }, { ...options, config }); +} + +export function declineRequest(runId: string, requestId: string, options: CrossmintClientOptions = {}): Promise { + return respond(runId, { requestId, action: "decline" }, options); +} + +export async function cancelCheckout(runId: string, options: CrossmintClientOptions = {}): Promise { + await request(`/agent-checkouts/${encodeURIComponent(runId)}/cancel`, { method: "POST" }, options); +} + +/** + * Saved name, contact, and shipping address that checkouts use instead of asking. It holds no + * payment data. Only the operator setup page reads or writes it; the model never sees it. + */ +export interface BuyerProfile { + id: string; + label?: string; + name?: { first: string; last: string }; + contact?: { email?: string; phone?: string }; + shipping: { addressLines: string[]; locality: string; countryCode: string; administrativeAreaCode?: string | null; postalCode?: string | null }; +} + +export type NewBuyerProfile = Omit; + +function projectBuyerProfile(raw: unknown): BuyerProfile { + const body = record(raw); + const shipping = record(body.shipping); + const id = string(body.id); + const lines = Array.isArray(shipping.addressLines) ? shipping.addressLines.filter((line): line is string => typeof line === "string") : []; + if (!id || !lines.length || !string(shipping.locality) || !string(shipping.countryCode)) throw new CrossmintRequestError("invalid_response"); + const name = record(body.name); + const contact = record(body.contact); + return { + id, + ...present({ label: string(body.label) }), + ...(string(name.first) && string(name.last) ? { name: { first: string(name.first)!, last: string(name.last)! } } : {}), + ...(string(contact.email) || string(contact.phone) ? { contact: present({ email: string(contact.email), phone: string(contact.phone) }) } : {}), + shipping: { + addressLines: lines, + locality: string(shipping.locality)!, + countryCode: string(shipping.countryCode)!, + administrativeAreaCode: string(shipping.administrativeAreaCode) ?? null, + postalCode: string(shipping.postalCode) ?? null, + }, + }; +} + +export async function getBuyerProfile(id: string, options: CrossmintClientOptions = {}): Promise { + return projectBuyerProfile(await request(`/agent-checkouts/buyer-profiles/${encodeURIComponent(id)}`, { method: "GET" }, options)); +} + +export async function createBuyerProfile(profile: NewBuyerProfile, options: CrossmintClientOptions = {}): Promise { + return projectBuyerProfile(await request("/agent-checkouts/buyer-profiles", { method: "POST", body: profile }, options)); +} + +/** Activity kinds, most telling first, and the phrase the person sees for them. */ +const STAGES: ReadonlyArray<[readonly string[], string]> = [ + [["apply_payment"], "Applying the payment"], + [["apply_buyer_information"], "Filling in the delivery details"], + [["create_checkout"], "Starting the store's checkout"], + [["call_webmcp_tool"], "Using the store's checkout tools"], + [["lookup_product", "search_catalog"], "Finding the product"], + [["navigate", "read_playbook"], "Opening the store"], +]; +const DEFAULT_STAGE = "Working through the store's checkout"; + +/** The latest stage in a run's messages, in any order Crossmint returns them. */ +export function projectProgress(messages: unknown[]): CheckoutProgress | undefined { + const latest = new Map(); + for (const raw of messages) { + const message = record(raw); + const id = string(message.id); + if (!id) continue; + const previous = latest.get(id); + if (!previous || Number(message.revision) >= Number(previous.revision)) latest.set(id, message); + } + const ordered = [...latest.values()].sort((a, b) => Date.parse(String(a.createdAt)) - Date.parse(String(b.createdAt))); + let stage: string | undefined; + for (const message of ordered) { + if (message.role !== "assistant" || !Array.isArray(message.parts)) continue; + for (const part of message.parts.map(record)) { + if (part.type !== "activity" || !Array.isArray(part.operations)) continue; + const kinds = new Set(part.operations.map((operation) => string(record(operation).kind)).filter(Boolean)); + stage = STAGES.find(([candidates]) => candidates.some((kind) => kinds.has(kind)))?.[1] ?? DEFAULT_STAGE; + } + } + return stage ? { stage } : undefined; +} + +/** Read the run's messages, at most five pages, and project its latest progress. */ +export async function getCheckoutProgress(runId: string, options: CrossmintClientOptions = {}): Promise { + const messages: unknown[] = []; + let cursor: string | undefined; + for (let page = 0; page < 5; page++) { + const query = `limit=100${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}`; + const body = record(await request(`/agent-checkouts/${encodeURIComponent(runId)}/messages?${query}`, { method: "GET" }, options)); + if (Array.isArray(body.data)) messages.push(...body.data); + cursor = string(body.nextCursor); + if (!cursor) break; + } + return projectProgress(messages); +} + +export interface WaitOptions extends CrossmintClientOptions { + /** Stop waiting after this many milliseconds and return the latest snapshot. */ + timeoutMs?: number; + intervalMs?: number; + /** A request id already answered. Crossmint can keep showing it briefly. */ + skipRequestId?: string; + /** + * Report progress while the run works: return early once the stage differs from this one (null + * means any stage), but not before `minProgressMs`, so the person gets one update per step. + */ + progressSince?: string | null; + minProgressMs?: number; +} + +function sleep(ms: number, signal?: AbortSignal): Promise { + return new Promise((resolve, reject) => { + const onAbort = () => { + clearTimeout(timer); + reject(signal?.reason); + }; + const timer = setTimeout(() => { + signal?.removeEventListener("abort", onAbort); + resolve(); + }, ms); + signal?.addEventListener("abort", onAbort, { once: true }); + }); +} + +/** Poll until the checkout needs input or ends, or until the timeout. Always returns a snapshot. */ +export async function waitForCheckout(runId: string, options: WaitOptions = {}): Promise { + const intervalMs = options.intervalMs ?? 2_000; + const started = Date.now(); + const deadline = started + (options.timeoutMs ?? 90_000); + const watchProgress = options.progressSince !== undefined; + let snapshot = await getCheckout(runId, options); + let progress: CheckoutProgress | undefined; + let progressReadAt = 0; + for (;;) { + const settled = + TERMINAL_STATUSES.has(snapshot.status) || + (snapshot.status === "awaiting_input" && snapshot.requiredAction !== null && snapshot.requiredAction.requestId !== options.skipRequestId); + if (settled) return snapshot; + const working = snapshot.status === "running" || snapshot.status === "queued"; + if (watchProgress && working && Date.now() - progressReadAt >= intervalMs * 3) { + progressReadAt = Date.now(); + // Progress is a courtesy: it never outlasts the wait, and only a cancellation stops it. + const remaining = AbortSignal.timeout(Math.max(1, deadline - Date.now())); + const signal = options.signal ? AbortSignal.any([options.signal, remaining]) : remaining; + progress = await getCheckoutProgress(runId, { ...options, signal }).catch((error: unknown) => { + if (options.signal?.aborted) throw error; + return progress; + }); + const changed = progress !== undefined && progress.stage !== options.progressSince; + if (changed && Date.now() - started >= (options.minProgressMs ?? 0)) return { ...snapshot, progress }; + } + if (Date.now() >= deadline) return watchProgress && working && progress ? { ...snapshot, progress } : snapshot; + options.signal?.throwIfAborted(); + await sleep(Math.min(intervalMs, Math.max(0, deadline - Date.now())), options.signal); + const next = await getCheckout(runId, options); + if (next.revision >= snapshot.revision) snapshot = next; + } +} diff --git a/server/crossmint/operator-jwt.ts b/server/crossmint/operator-jwt.ts new file mode 100644 index 0000000..24773aa --- /dev/null +++ b/server/crossmint/operator-jwt.ts @@ -0,0 +1,57 @@ +import { createHash, createPrivateKey, createPublicKey, sign, type KeyObject } from "node:crypto"; + +/** + * The operator's JWT for Crossmint Agent Cards. + * + * Crossmint accepts order intent calls only with the user's JWT. Bell serves one trusted operator, + * so it issues that JWT itself as the project's custom JWT provider: RS256, `iss` the Crossmint + * project id, `sub` the operator's CROSSMINT_USER_ID, `aud` crossmint.com, ten minutes. Crossmint + * checks the signature against the JWKS Bell serves at /api/crossmint/jwks. + * Guide: https://docs.crossmint.com/introduction/platform/api-keys/custom-jwt-auth-guide + * + * This file uses only erasable TypeScript, so scripts/crossmint-operator-jwt.mjs can load it. + */ + +export const JWT_TTL_SECONDS = 600; +const AUDIENCE = "crossmint.com"; + +export interface OperatorJwtConfig { + projectId: string; + userId: string; + privateKey: KeyObject; +} + +/** Read CROSSMINT_JWT_PRIVATE_KEY: a PEM RSA private key, base64 encoded as in Crossmint's guide, or plain. */ +export function parseRsaPrivateKey(value: string): KeyObject | undefined { + const text = value.includes("-----BEGIN") ? value : Buffer.from(value, "base64").toString("utf8"); + try { + const key = createPrivateKey(text); + const bits = key.asymmetricKeyDetails?.modulusLength ?? 0; + return key.asymmetricKeyType === "rsa" && bits >= 2048 ? key : undefined; + } catch { + return undefined; + } +} + +function publicJwk(privateKey: KeyObject): { kty: "RSA"; n: string; e: string; kid: string } { + const { n, e } = createPublicKey(privateKey).export({ format: "jwk" }); + if (typeof n !== "string" || typeof e !== "string") throw new Error("The operator key is not an RSA key."); + // RFC 7638 thumbprint: the required members in lexicographic order. + const kid = createHash("sha256").update(JSON.stringify({ e, kty: "RSA", n })).digest("base64url"); + return { kty: "RSA", n, e, kid }; +} + +/** The public half of the operator key, as the JWKS Crossmint fetches. */ +export function operatorJwks(privateKey: KeyObject) { + return { keys: [{ ...publicJwk(privateKey), alg: "RS256", use: "sig" }] }; +} + +/** Sign a short-lived operator JWT. It stays on the server, except on the operator-only setup page. */ +export function operatorJwt(config: OperatorJwtConfig, now = Date.now()): string { + const iat = Math.floor(now / 1000); + const encode = (value: object) => Buffer.from(JSON.stringify(value)).toString("base64url"); + const header = encode({ alg: "RS256", typ: "JWT", kid: publicJwk(config.privateKey).kid }); + const payload = encode({ iss: config.projectId, sub: config.userId, aud: AUDIENCE, iat, exp: iat + JWT_TTL_SECONDS }); + const signature = sign("sha256", Buffer.from(`${header}.${payload}`), config.privateKey).toString("base64url"); + return `${header}.${payload}.${signature}`; +} diff --git a/server/crossmint/operator.ts b/server/crossmint/operator.ts new file mode 100644 index 0000000..ba0dd31 --- /dev/null +++ b/server/crossmint/operator.ts @@ -0,0 +1,247 @@ +import type { KeyObject } from "node:crypto"; +import { z } from "zod"; +import { crossmintConfig, CrossmintRequestError, CrossmintSetupError, type CrossmintConfig } from "./client"; +import { operatorJwt, parseRsaPrivateKey } from "./operator-jwt"; + +/** + * Calls Crossmint makes only for a signed-in user: saving and registering cards, and approving, + * listing, and cancelling order intents. They take a client key with the user's JWT, never a server + * key. Bell serves one operator, so it signs that JWT itself (operator-jwt.ts) and sends Bell's + * origin, which must be an allowed origin of the client key. + * + * These calls serve the operator setup page. None of their results reach the model. + * API reference: https://docs.crossmint.com/api-reference/agentic-commerce/order-intents/list-order-intents + */ + +export interface OperatorConfig extends CrossmintConfig { + /** Client key (ck_). */ + clientApiKey: string; + /** Crossmint project id, the `iss` of the operator JWT. */ + projectId: string; + privateKey: KeyObject; + /** Bell's origin, sent with every call. */ + origin: string; +} + +export const OPERATOR_SETTINGS = ["CROSSMINT_CLIENT_API_KEY", "CROSSMINT_PROJECT_ID", "CROSSMINT_JWT_PRIVATE_KEY"] as const; + +export function isOperatorConfigured(env: Record = process.env): boolean { + return OPERATOR_SETTINGS.every((name) => Boolean(env[name]?.trim())); +} + +export function operatorConfig(env: Record = process.env): OperatorConfig { + const base = crossmintConfig(env); + const required = (name: string) => { + const value = env[name]?.trim(); + if (!value) throw new CrossmintSetupError("missing_configuration", name); + return value; + }; + const invalid = (name: string) => new CrossmintSetupError("invalid_configuration", name); + + const clientApiKey = required("CROSSMINT_CLIENT_API_KEY"); + const production = new URL(base.baseUrl).hostname === "www.crossmint.com"; + if (!clientApiKey.startsWith("ck_") || clientApiKey.startsWith("ck_production_") !== production) throw invalid("CROSSMINT_CLIENT_API_KEY"); + const projectId = required("CROSSMINT_PROJECT_ID"); + const privateKey = parseRsaPrivateKey(required("CROSSMINT_JWT_PRIVATE_KEY")); + if (!privateKey) throw invalid("CROSSMINT_JWT_PRIVATE_KEY"); + + const publicUrl = URL.parse(required("BELL_PUBLIC_URL")); + const loopback = publicUrl?.protocol === "http:" && /^(?:localhost|127\.0\.0\.1|\[::1\])$/.test(publicUrl.hostname); + if (!publicUrl || publicUrl.username || publicUrl.password || (publicUrl.protocol !== "https:" && !loopback)) throw invalid("BELL_PUBLIC_URL"); + + return { ...base, clientApiKey, projectId, privateKey, origin: publicUrl.origin }; +} + +/** + * A refused operator call. `detail` is Crossmint's own message, shown to the operator on the setup + * page because it names the fix (for example a missing consumer email). It never reaches the model. + */ +export class CrossmintOperatorError extends Error { + constructor( + readonly reason: "unauthorized" | "not_found" | "rejected", + readonly status: number, + readonly detail?: string, + ) { + super( + reason === "unauthorized" + ? "Crossmint rejected the client key, its allowed origins, or Bell's operator token." + : reason === "not_found" + ? "Crossmint found nothing with that id for this operator." + : `Crossmint refused the request (HTTP ${status}).`, + ); + this.name = "CrossmintOperatorError"; + } +} + +export interface OperatorClientOptions { + config?: OperatorConfig; + fetch?: typeof fetch; + signal?: AbortSignal; +} + +const REQUEST_TIMEOUT_MS = 20_000; + +/** One call with the client key, the operator JWT, and Bell's origin. */ +export async function operatorRequest( + path: string, + init: { method: "GET" | "POST" | "PUT" | "DELETE"; body?: unknown; idempotencyKey?: string }, + options: OperatorClientOptions = {}, +): Promise { + const config = options.config ?? operatorConfig(); + const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS); + const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout; + signal.throwIfAborted(); + try { + return await (options.fetch ?? fetch)(`${config.baseUrl}${path}`, { + method: init.method, + headers: { + "X-API-KEY": config.clientApiKey, + Authorization: `Bearer ${operatorJwt(config)}`, + Origin: config.origin, + ...(init.body !== undefined ? { "Content-Type": "application/json" } : {}), + ...(init.idempotencyKey ? { "Idempotency-Key": init.idempotencyKey } : {}), + }, + body: init.body !== undefined ? JSON.stringify(init.body) : undefined, + redirect: "error", + signal, + }); + } catch { + options.signal?.throwIfAborted(); + throw new CrossmintRequestError("transport"); + } +} + +async function json(response: Response): Promise { + if (!response.ok) { + let detail: string | undefined; + try { + const body = (await response.json()) as { message?: unknown; error?: unknown }; + const text = (value: unknown) => + typeof value === "string" ? value : Array.isArray(value) ? value.filter((item) => typeof item === "string").join("; ") : undefined; + detail = (text(body.message) || text(body.error))?.slice(0, 300) || undefined; + } catch { + detail = undefined; + } + const reason = response.status === 401 || response.status === 403 ? "unauthorized" : response.status === 404 ? "not_found" : "rejected"; + throw new CrossmintOperatorError(reason, response.status, detail); + } + if (response.status === 204) return null; + const text = await response.text().catch(() => ""); + if (!text.trim()) return null; + try { + return JSON.parse(text) as unknown; + } catch { + throw new CrossmintRequestError("invalid_response", response.status); + } +} + +const railSchema = z.object({ + rail: z.string(), + provider: z.string().optional(), + status: z.string(), + credentialFormats: z.array(z.string()).optional(), + error: z.object({ code: z.string().optional() }).nullish(), +}); + +const merchantSchema = z.object({ name: z.string().optional(), url: z.string(), countryCode: z.string().optional() }); + +const decimal = z.string().regex(/^\d+(?:\.\d+)?$/); + +export const orderIntentSchema = z.object({ + orderIntentId: z.string(), + paymentMethodId: z.string().optional(), + status: z.string(), + amount: z.object({ total: decimal.optional(), spent: decimal.optional(), available: decimal, currency: z.string() }), + merchant: merchantSchema.nullish(), + description: z.string().optional(), + expiresAt: z.string(), + rails: z.array(railSchema), + verificationConfig: z.unknown().optional(), +}); + +export type OrderIntentSummary = z.infer; + +const registrationSchema = z.object({ + paymentMethodId: z.string(), + rails: z.array(railSchema), +}); + +export type CardRegistration = z.infer; + +/** What a card-network rail needs to know about the person, sent once per saved card. */ +export interface Consumer { + email: string; + /** ISO 3166-1 alpha-2. */ + countryCode: string; + /** BCP 47, such as en-US or es-ES. */ + languageCode: string; +} + +/** The card's order-intent registration, or null when the card was never registered. */ +export async function getRegistration(paymentMethodId: string, options: OperatorClientOptions = {}): Promise { + const path = `/payment-methods/${encodeURIComponent(paymentMethodId)}/order-intent-registration`; + try { + const parsed = registrationSchema.safeParse(await json(await operatorRequest(path, { method: "GET" }, options))); + if (!parsed.success) throw new CrossmintRequestError("invalid_response"); + return parsed.data; + } catch (error) { + if (error instanceof CrossmintOperatorError && error.reason === "not_found") return null; + throw error; + } +} + +/** + * Register a saved card for order intents with the person's email, country, and language. Crossmint + * needs the email to provision card-network rails, and Bell's operator JWT carries none, so an + * empty registration is refused. Registering is idempotent and grants no spending. + */ +export async function registerCard(paymentMethodId: string, consumer: Consumer, options: OperatorClientOptions = {}): Promise { + const path = `/payment-methods/${encodeURIComponent(paymentMethodId)}/order-intent-registration`; + const body = { email: consumer.email, countryCode: consumer.countryCode.toUpperCase(), languageCode: consumer.languageCode }; + const parsed = registrationSchema.safeParse(await json(await operatorRequest(path, { method: "PUT", body }, options))); + if (!parsed.success) throw new CrossmintRequestError("invalid_response"); + return parsed.data; +} + +/** Every order intent of the operator, newest expiry first. */ +export async function listOrderIntents(options: OperatorClientOptions = {}): Promise { + const raw = await json(await operatorRequest("/order-intents", { method: "GET" }, options)); + const parsed = z.array(orderIntentSchema).safeParse(Array.isArray(raw) ? raw : (raw as { data?: unknown } | null)?.data); + if (!parsed.success) throw new CrossmintRequestError("invalid_response"); + return parsed.data.sort((a, b) => Date.parse(b.expiresAt) - Date.parse(a.expiresAt)); +} + +export interface NewOrderIntent { + paymentMethodId: string; + amount: { value: string; currency: string }; + merchant: { name: string; url: string; countryCode: string }; + description: string; + expiresAt: string; +} + +/** Approve a budget on a saved, registered card for one merchant. */ +export async function createOrderIntent( + input: NewOrderIntent, + options: OperatorClientOptions & { idempotencyKey?: string } = {}, +): Promise { + const body = { ...input, amount: { value: input.amount.value, currency: input.amount.currency.toUpperCase() } }; + const init = { method: "POST" as const, body, ...(options.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}) }; + const parsed = orderIntentSchema.safeParse(await json(await operatorRequest("/order-intents", init, options))); + if (!parsed.success) throw new CrossmintRequestError("invalid_response"); + return parsed.data; +} + +/** Cancel an order intent. Later reads show it as cancelled and nothing more can be spent. */ +export async function cancelOrderIntent(orderIntentId: string, options: OperatorClientOptions = {}): Promise { + await json(await operatorRequest(`/order-intents/${encodeURIComponent(orderIntentId)}`, { method: "DELETE" }, options)); +} + +/** Rails as the setup page shows them. Agent Checkouts can pay even when none is active. */ +export function describeRail(rail: z.infer): string { + const name = + rail.rail === "agentic-token" + ? rail.provider === "vic" ? "Visa Intelligent Commerce" : rail.provider === "agentpay" ? "Mastercard Agent Pay" : "Card network token" + : rail.rail === "encrypted-card" ? "Encrypted card" + : rail.rail === "spt" ? "Stripe shared payment token" : rail.rail; + return `${name}: ${rail.status.replaceAll("_", " ")}`; +} diff --git a/server/crossmint/payment.ts b/server/crossmint/payment.ts new file mode 100644 index 0000000..678cdfa --- /dev/null +++ b/server/crossmint/payment.ts @@ -0,0 +1,76 @@ +import { compareAmounts, type CheckoutSnapshot, type MaxCost } from "./client"; +import type { CheckoutRecord } from "./runs"; + +/** The payment the person approved, as the model stated it in the tool call. */ +export interface ApprovedPayment { + requestId: string; + amount: string; + currency: string; + merchant: string; + /** The store name the approval dialog showed, when the model gave one. */ + merchantName?: string; +} + +export class PaymentMismatchError extends Error { + constructor( + readonly reason: + | "no_payment_request" + | "request_changed" + | "unsupported_method" + | "unsupported_amount" + | "currency_mismatch" + | "amount_mismatch" + | "merchant_mismatch" + | "cap_exceeded", + message: string, + ) { + super(message); + this.name = "PaymentMismatchError"; + } +} + +export function hostOf(value: string): string | undefined { + return URL.parse(value.includes("://") ? value : `https://${value}`)?.hostname.toLowerCase(); +} + +/** + * Compare the approved payment with the request Crossmint is showing right now and with the cap + * the run was created under. Anything that differs refuses the payment. The approval dialog shows + * the person the model's numbers; this check makes sure those are also Crossmint's numbers. + */ +export function assertPaymentMatches(approved: ApprovedPayment, live: CheckoutSnapshot, record: CheckoutRecord): { amount: MaxCost; merchant: string } { + const refuse = (reason: PaymentMismatchError["reason"], message: string) => new PaymentMismatchError(reason, message); + const action = live.requiredAction; + if (live.status !== "awaiting_input" || !action || action.interaction.kind !== "payment") { + throw refuse("no_payment_request", "Crossmint is not waiting for a payment on this checkout."); + } + if (action.requestId !== approved.requestId) { + throw refuse("request_changed", "The payment request changed since approval. Show the person the new request."); + } + const { method, amount, merchant } = action.interaction; + if (method !== "card") { + throw refuse("unsupported_method", `Crossmint is asking for a ${method} payment, which an order intent cannot pay. Decline and tell the person.`); + } + if (amount.kind !== "exact") { + throw refuse("unsupported_amount", "Crossmint sent a maximum rather than an exact total. Decline and ask the person how to proceed."); + } + if (amount.currency !== approved.currency) { + throw refuse("currency_mismatch", "The approved currency differs from Crossmint's."); + } + if (compareAmounts(amount.value, approved.amount) !== 0) { + throw refuse("amount_mismatch", `Crossmint is asking for ${amount.value} ${amount.currency}, not the approved amount.`); + } + const liveHost = merchant.url ? hostOf(merchant.url) : undefined; + if (!liveHost || liveHost !== hostOf(approved.merchant)) { + throw refuse("merchant_mismatch", "The approved merchant differs from the one Crossmint is checking out at."); + } + // The dialog showed this name to the person, so it must be Crossmint's name, not the model's. + const shownName = approved.merchantName?.trim().toLowerCase(); + if (shownName && shownName !== merchant.name?.trim().toLowerCase()) { + throw refuse("merchant_mismatch", "The approved store name differs from the one Crossmint is checking out at."); + } + if (record.maxCost.currency !== amount.currency || compareAmounts(amount.value, record.maxCost.amount) > 0) { + throw refuse("cap_exceeded", `The total exceeds the ${record.maxCost.amount} ${record.maxCost.currency} cap this checkout was started with.`); + } + return { amount: { amount: amount.value, currency: amount.currency }, merchant: liveHost }; +} diff --git a/server/crossmint/runs.ts b/server/crossmint/runs.ts new file mode 100644 index 0000000..9fa18d4 --- /dev/null +++ b/server/crossmint/runs.ts @@ -0,0 +1,43 @@ +import type { MaxCost } from "./client"; + +/** + * Checkouts started in this process, keyed by Eve session. A conversation can only read, answer, + * pay for, or cancel a checkout it started, so a model-supplied id cannot reach another buyer's + * run. The cap each run was created with is kept here and checked again at payment time. + * + * The registry lives in process memory. After a restart or a worker change an unfinished checkout + * is reconciled in the Crossmint console, not retried here. + */ +export interface CheckoutRecord { + runId: string; + maxCost: MaxCost; + /** Authenticated principal that started the run, when the channel provided one. */ + principalId: string | null; + /** The last progress stage reported to the person, so each update says something new. */ + lastStage?: string; +} + +const runs = new Map>(); + +export function rememberCheckout(sessionId: string, record: CheckoutRecord): void { + let session = runs.get(sessionId); + if (!session) { + session = new Map(); + runs.set(sessionId, session); + } + session.set(record.runId, record); +} + +export function sessionCheckout(sessionId: string, runId: string): CheckoutRecord | undefined { + return runs.get(sessionId)?.get(runId); +} + +export function assertSessionCheckout(sessionId: string, runId: string): CheckoutRecord { + const record = sessionCheckout(sessionId, runId); + if (!record) { + throw new Error( + "This conversation did not start that checkout in this process. Start a new checkout, or reconcile the existing one in the Crossmint console.", + ); + } + return record; +} diff --git a/tests/crossmint-cards.test.ts b/tests/crossmint-cards.test.ts new file mode 100644 index 0000000..7bf468d --- /dev/null +++ b/tests/crossmint-cards.test.ts @@ -0,0 +1,430 @@ +import { createPublicKey, generateKeyPairSync, verify } from "node:crypto"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { + assertCardPayment, + cardConfig, + cardRequest, + checkoutAmount, + CrossmintCardError, + getOrderIntent, + idempotencyKey, + isCrossmintCardsConfigured, + merchantOrigin, + mintCard, + paymentOrigins, + projectCard, + type CardReason, + type OrderIntent, +} from "../server/crossmint/cards.js"; +import { CrossmintRequestError } from "../server/crossmint/client.js"; +import { operatorJwks, operatorJwt, parseRsaPrivateKey } from "../server/crossmint/operator-jwt.js"; +import { paymentValues, type CheckoutInput } from "../server/link/payment.js"; +import { withBrowserPrivacyLock } from "../server/browser/privacy-lock.js"; +import { GET as jwksRoute } from "../app/api/crossmint/jwks/route.js"; +import cardTool from "../agent/tools/crossmint_card_checkout.js"; +import { runBrowserOperation } from "../agent/lib/browser-runtime.js"; +import { checkoutInHostedPage } from "../server/link/checkout-browser.js"; + +vi.mock("../agent/lib/browser-runtime", () => ({ + runCancelableBrowserWork: (_id: string, _signal: AbortSignal, operation: () => unknown) => operation(), + runBrowserOperation: vi.fn(async (_id: string, operation: (browser: unknown) => unknown) => ({ + result: await operation({ + withHostedPage: (_signal: AbortSignal, call: (page: unknown, url: string) => unknown, privateResult: boolean) => { + expect(privateResult).toBe(true); + return call({}, "private-connection"); + }, + }), + workbench: { private: "not-returned" }, + })), +})); +vi.mock("../server/link/checkout-browser", () => ({ checkoutInHostedPage: vi.fn() })); +const lock = vi.hoisted(() => ({ held: true })); +vi.mock("../server/browser/privacy-lock", async (importOriginal) => ({ + ...(await importOriginal()), + hasBrowserPrivacyLock: () => lock.held, +})); + +const { privateKey } = generateKeyPairSync("rsa", { modulusLength: 2048 }); +const privatePem = privateKey.export({ type: "pkcs8", format: "pem" }).toString(); +const NUMBER = "4000001000004242"; +const CVC = "735"; +const future = () => new Date(Date.now() + 86_400_000).toISOString(); + +const env = { + CROSSMINT_SERVER_API_KEY: "sk_unit_test_only", + CROSSMINT_USER_ID: "operator-1", + CROSSMINT_CLIENT_API_KEY: "ck_production_unit_test_only", + CROSSMINT_PROJECT_ID: "project-1", + CROSSMINT_JWT_PRIVATE_KEY: Buffer.from(privatePem).toString("base64"), + CROSSMINT_ORDER_INTENT_ID: "oi_test_secret", + CROSSMINT_CHECKOUT_ORIGINS: JSON.stringify({ "https://shop.example": ["https://pay.example"] }), + CROSSMINT_CARD_CHECKOUT: "1", + BELL_PUBLIC_URL: "https://bell.example", +}; + +const intent = (overrides: Partial> = {}) => ({ + orderIntentId: "oi_test_secret", + paymentMethodId: "pm_1", + status: "active", + amount: { total: "50.00", spent: "0.00", reserved: "0.00", available: "50.00", currency: "USD" }, + description: "Groceries", + expiresAt: future(), + merchant: { name: "Example Shop", url: "https://shop.example", countryCode: "US" }, + rails: [ + { rail: "agentic-token", provider: "vic", status: "active", credentialFormats: ["card", "network-token"] }, + { rail: "encrypted-card", status: "active", credentialFormats: ["card"] }, + ], + ...overrides, +}); + +const issued = (overrides: Record = {}) => ({ + id: "cred_1", + rail: "agentic-token", + provider: "vic", + amount: { value: "12.49", currency: "USD" }, + expiresAt: future(), + credential: { format: "card", value: { number: NUMBER, expirationMonth: 12, expirationYear: 2030, cvc: CVC } }, + ...overrides, +}); + +const payment = { amount: "12.49", currency: "USD", merchant: "https://shop.example" }; +const refusal = (run: () => unknown) => { + try { + run(); + } catch (error) { + if (error instanceof CrossmintCardError) return error.reason; + throw error; + } + return "allowed"; +}; + +describe("Crossmint Agent Cards configuration", () => { + it("is optional until the card settings are present and paying in Bell's browser is switched on", () => { + expect(isCrossmintCardsConfigured({})).toBe(false); + expect(isCrossmintCardsConfigured({ ...env, CROSSMINT_CLIENT_API_KEY: "" })).toBe(false); + // The setup keys alone approve budgets for Agent Checkouts; they never add the card tool. + expect(isCrossmintCardsConfigured({ ...env, CROSSMINT_CARD_CHECKOUT: "" })).toBe(false); + expect(isCrossmintCardsConfigured({ ...env, CROSSMINT_CARD_CHECKOUT: "true" })).toBe(false); + expect(isCrossmintCardsConfigured(env)).toBe(true); + }); + + it("names the missing or invalid setting without logging values", () => { + expect(() => cardConfig({ ...env, CROSSMINT_PROJECT_ID: "" })).toThrow("CROSSMINT_PROJECT_ID"); + expect(() => cardConfig({ ...env, CROSSMINT_CLIENT_API_KEY: "sk_server_key" })).toThrow("CROSSMINT_CLIENT_API_KEY"); + expect(() => cardConfig({ ...env, CROSSMINT_CLIENT_API_KEY: "ck_staging_unit" })).toThrow("CROSSMINT_CLIENT_API_KEY"); + expect(() => cardConfig({ ...env, CROSSMINT_JWT_PRIVATE_KEY: "bm90IGEga2V5" })).toThrow("CROSSMINT_JWT_PRIVATE_KEY"); + expect(() => cardConfig({ ...env, BELL_PUBLIC_URL: "http://bell.example" })).toThrow("BELL_PUBLIC_URL"); + expect(() => cardConfig({ ...env, CROSSMINT_CHECKOUT_ORIGINS: "{not json" })).toThrow("CROSSMINT_CHECKOUT_ORIGINS"); + expect(() => cardConfig({ ...env, CROSSMINT_CHECKOUT_ORIGINS: '{"https://shop.example":["https://pay.example/frame"]}' })).toThrow("CROSSMINT_CHECKOUT_ORIGINS"); + expect(() => cardConfig({ ...env, CROSSMINT_JWT_PRIVATE_KEY: "bm90IGEga2V5" })).toThrow(/^Check CROSSMINT_JWT_PRIVATE_KEY in the server configuration\.$/); + }); + + it("matches the client key to the environment and keeps Bell's origin", () => { + const staging = cardConfig({ ...env, CROSSMINT_API_BASE_URL: "https://staging.crossmint.com/api/unstable", CROSSMINT_CLIENT_API_KEY: "ck_staging_unit", BELL_PUBLIC_URL: "http://127.0.0.1:4320" }); + expect(staging.origin).toBe("http://127.0.0.1:4320"); + expect(paymentOrigins(staging, "https://shop.example")).toEqual(["https://shop.example", "https://pay.example"]); + expect(paymentOrigins(staging, "https://other.example")).toEqual(["https://other.example"]); + }); +}); + +describe("Crossmint operator JWT", () => { + it("signs a ten-minute RS256 token for the operator that the JWKS verifies", () => { + const config = cardConfig(env); + const token = operatorJwt(config, Date.parse("2026-10-28T12:00:00Z")); + const [header, payload, signature] = token.split("."); + const jwks = operatorJwks(config.privateKey); + const { alg, kid } = JSON.parse(Buffer.from(header, "base64url").toString()); + expect({ alg, kid }).toEqual({ alg: "RS256", kid: jwks.keys[0].kid }); + expect(JSON.parse(Buffer.from(payload, "base64url").toString())).toEqual({ iss: "project-1", sub: "operator-1", aud: "crossmint.com", iat: 1793188800, exp: 1793189400 }); + const publicKey = createPublicKey({ key: jwks.keys[0], format: "jwk" }); + expect(verify("sha256", Buffer.from(`${header}.${payload}`), publicKey, Buffer.from(signature, "base64url"))).toBe(true); + }); + + it("accepts plain or base64 PEM keys and refuses weak or non-RSA keys", () => { + expect(parseRsaPrivateKey(privatePem)).toBeDefined(); + expect(parseRsaPrivateKey(generateKeyPairSync("rsa", { modulusLength: 1024 }).privateKey.export({ type: "pkcs8", format: "pem" }).toString())).toBeUndefined(); + expect(parseRsaPrivateKey(generateKeyPairSync("ec", { namedCurve: "P-256" }).privateKey.export({ type: "pkcs8", format: "pem" }).toString())).toBeUndefined(); + }); + + it("serves only the public key", async () => { + vi.stubEnv("CROSSMINT_JWT_PRIVATE_KEY", ""); + expect(jwksRoute().status).toBe(404); + vi.stubEnv("CROSSMINT_JWT_PRIVATE_KEY", "bm90IGEga2V5"); + expect(jwksRoute().status).toBe(500); + vi.stubEnv("CROSSMINT_JWT_PRIVATE_KEY", env.CROSSMINT_JWT_PRIVATE_KEY); + const response = jwksRoute(); + const body = await response.json(); + expect(response.headers.get("cache-control")).toBe("public, max-age=300"); + expect(body.keys).toHaveLength(1); + expect(Object.keys(body.keys[0]).sort()).toEqual(["alg", "e", "kid", "kty", "n", "use"]); + vi.unstubAllEnvs(); + }); +}); + +describe("Crossmint order intent checks", () => { + const check = (overrides: Parameters[0], paid = payment) => refusal(() => assertCardPayment(intent(overrides) as OrderIntent, paid)); + + it("returns the active card network rail", () => { + expect(assertCardPayment(intent() as OrderIntent, payment)).toEqual({ provider: "vic" }); + const rails = [{ rail: "agentic-token", provider: "vic", status: "pending_verification" }, { rail: "agentic-token", provider: "agentpay", status: "active", credentialFormats: ["card"] }]; + expect(assertCardPayment(intent({ rails }) as OrderIntent, payment)).toEqual({ provider: "agentpay" }); + }); + + it("refuses with its own reason for each mismatch", () => { + const cases: [Parameters[0], CardReason, typeof payment?][] = [ + [{ status: "expired" }, "order_intent_expired"], + [{ status: "cancelled" }, "order_intent_inactive"], + [{ expiresAt: new Date(Date.now() + 30_000).toISOString() }, "order_intent_expired"], + [{ expiresAt: "not a date" }, "order_intent_expired"], + [{ merchant: undefined }, "merchant_scope_required"], + [{}, "merchant_mismatch", { ...payment, merchant: "https://shop.example.evil" }], + [{ merchant: { name: "Shop", url: "https://www.shop.example", countryCode: "US" } }, "merchant_mismatch"], + [{}, "currency_mismatch", { ...payment, currency: "EUR" }], + [{ amount: { total: "50.00", spent: "40.00", reserved: "0.00", available: "10.00", currency: "USD" } }, "insufficient_allowance"], + [{ rails: [{ rail: "agentic-token", provider: "vic", status: "pending_verification", credentialFormats: ["card"] }] }, "rail_pending_verification"], + [{ rails: [{ rail: "agentic-token", provider: "agentpay", status: "error", credentialFormats: [], error: { code: "CARD_REJECTED" } }] }, "rail_error"], + [{ rails: [{ rail: "encrypted-card", status: "active", credentialFormats: ["card"] }] }, "no_card_rail"], + [{ rails: [{ rail: "agentic-token", provider: "vic", status: "active", credentialFormats: ["network-token"] }] }, "no_card_rail"], + ]; + for (const [overrides, reason, paid] of cases) expect(check(overrides, paid), reason).toBe(reason); + }); + + it("reads merchants and amounts the way the fill needs them", () => { + expect(merchantOrigin("shop.example")).toBe("https://shop.example"); + expect(merchantOrigin("https://shop.example/checkout?step=pay")).toBe("https://shop.example"); + expect(refusal(() => merchantOrigin("http://shop.example"))).toBe("invalid_merchant"); + expect(refusal(() => merchantOrigin("https://user:pass@shop.example"))).toBe("invalid_merchant"); + expect(checkoutAmount("12.49", "USD")).toBe(1249); + expect(checkoutAmount("1500", "JPY")).toBe(1500); + expect(refusal(() => checkoutAmount("1500.50", "JPY"))).toBe("unsupported_amount"); + }); +}); + +describe("Crossmint card mint", () => { + const config = cardConfig(env); + const fetchReturning = (status: number, body: unknown) => vi.fn(async () => new Response(JSON.stringify(body), { status })); + + it("reads the order intent with the client key, operator token, and Bell's origin", async () => { + const fetcher = fetchReturning(200, intent()); + await getOrderIntent({ config, fetch: fetcher }); + const [url, init] = fetcher.mock.calls[0] as unknown as [string, RequestInit & { headers: Record }]; + expect(url).toBe("https://www.crossmint.com/api/unstable/order-intents/oi_test_secret"); + expect(init).toMatchObject({ method: "GET", redirect: "error", body: undefined }); + expect(init.headers).toMatchObject({ "X-API-KEY": "ck_production_unit_test_only", Origin: "https://bell.example" }); + expect(init.headers.Authorization).toMatch(/^Bearer [\w-]+\.[\w-]+\.[\w-]+$/); + expect(init.headers).not.toHaveProperty("Idempotency-Key"); + expect(JSON.stringify(init.headers)).not.toContain("sk_unit_test_only"); + }); + + it("mints exactly the approved amount on the network rail with the call's idempotency key", async () => { + const fetcher = fetchReturning(201, issued()); + const key = idempotencyKey("session-1", "call-1"); + const card = await mintCard("vic", { amount: "12.49", currency: "USD" }, key, { config, fetch: fetcher }); + const [url, init] = fetcher.mock.calls[0] as unknown as [string, RequestInit & { headers: Record }]; + expect(url).toBe("https://www.crossmint.com/api/unstable/order-intents/oi_test_secret/credentials"); + expect(init.method).toBe("POST"); + expect(init.headers).toMatchObject({ "Idempotency-Key": key, "Content-Type": "application/json" }); + expect(JSON.parse(init.body as string)).toEqual({ rail: "agentic-token", provider: "vic", amount: { value: "12.49", currency: "USD" }, credential: { format: "card" } }); + expect(card.card).toMatchObject({ number: NUMBER, cvc: CVC, exp_month: 12, exp_year: 2030 }); + }); + + it("derives one stable key per tool call", () => { + const key = idempotencyKey("session-1", "call-1"); + expect(key).toMatch(/^bell-card-[0-9a-f]{64}$/); + expect(idempotencyKey("session-1", "call-1")).toBe(key); + expect(idempotencyKey("session-1", "call-2")).not.toBe(key); + expect(idempotencyKey("session-2", "call-1")).not.toBe(key); + expect(key).not.toContain("session-1"); + }); + + it("projects the card into the fields Bell's fill maps", () => { + const input = { fields: ["number", "cvc", "expiry", "exp_month", "exp_year"].map((field) => ({ field, selector: `#${field}` })) } as CheckoutInput; + expect(paymentValues(projectCard(issued(), { amount: "12.49", currency: "USD" }), input)).toEqual([NUMBER, CVC, "12/30", "12", "2030"]); + const short = issued({ credential: { format: "card", value: { number: NUMBER, expirationMonth: 3, expirationYear: 31, cvc: CVC } } }); + expect(paymentValues(projectCard(short, { amount: "12.49", currency: "USD" }), input).slice(2)).toEqual(["03/31", "03", "2031"]); + }); + + it("refuses a credential that does not match the request", () => { + for (const raw of [issued({ amount: { value: "12.50", currency: "USD" } }), issued({ rail: "encrypted-card" }), issued({ credential: { format: "network-token", value: {} } }), {}]) { + expect(refusal(() => projectCard(raw, { amount: "12.49", currency: "USD" }))).toBe("unexpected_credential"); + } + }); + + it("maps the codes an operator must act on and never echoes Crossmint's message", async () => { + const codes: [number, string, CardReason][] = [ + [409, "ORDER_INTENT_CVC_RECOLLECTION_REQUIRED", "cvc_recollection_required"], + [409, "payments:payment-method.deleted", "payment_method_deleted"], + [409, "ORDER_INTENT_CREDENTIAL_ALREADY_ISSUED", "credential_already_issued"], + [409, "ORDER_INTENT_PROVIDER_OPERATION_IN_PROGRESS", "retry_later"], + [400, "ORDER_INTENT_AMOUNT_EXCEEDED", "insufficient_allowance"], + [400, "ORDER_INTENT_EXPIRED", "order_intent_expired"], + [400, "ORDER_INTENT_CANCELLED", "order_intent_inactive"], + [400, "ORDER_INTENT_CREDENTIAL_UNAVAILABLE", "credential_unavailable"], + ]; + for (const [status, code, reason] of codes) { + const error = await mintCard("vic", { amount: "12.49", currency: "USD" }, "k", { config, fetch: fetchReturning(status, { error: true, code, message: `secret provider text ${NUMBER}` }) }).catch((e: unknown) => e); + expect(error, code).toBeInstanceOf(CrossmintCardError); + expect((error as CrossmintCardError).reason).toBe(reason); + expect((error as Error).message).not.toContain("secret provider text"); + } + }); + + it("maps statuses without a known code", async () => { + const reasonOf = (status: number, body: unknown = { error: true, message: "secret provider text" }) => + cardRequest("/order-intents/x", { method: "GET" }, { config, fetch: fetchReturning(status, body) }).catch((error: unknown) => error); + expect(await reasonOf(401)).toMatchObject({ reason: "unauthorized" }); + expect(await reasonOf(403, { code: "constructor" })).toMatchObject({ reason: "unauthorized" }); + expect(await reasonOf(404)).toMatchObject({ reason: "order_intent_not_found" }); + expect(await reasonOf(429)).toEqual(new CrossmintRequestError("rate_limited", 429)); + expect(await reasonOf(409, { code: "SOMETHING_NEW" })).toEqual(new CrossmintRequestError("http_error", 409)); + expect(await cardRequest("/x", { method: "GET" }, { config, fetch: vi.fn(async () => { throw new Error("socket"); }) }).catch((e: unknown) => e)).toEqual(new CrossmintRequestError("transport")); + }); +}); + +describe("Crossmint card checkout tool", () => { + const principal = { principalId: "linq:1", principalType: "user", authenticator: "linq-message", attributes: {} }; + const ctx = (auth: typeof principal | null = principal, callId = "call-1") => ({ session: { id: "session-cards", auth: { current: auth, initiator: auth } }, callId, abortSignal: new AbortController().signal }); + const input = { + amount: "12.49", + currency: "USD", + merchant: "shop.example", + fields: [{ field: "number" as const, selector: "#number" }, { field: "cvc" as const, selector: "#cvc", frame: "#card" }, { field: "expiry" as const, selector: "#expiry" }], + submit: { selector: "#pay" }, + }; + // Every tool output in this block is checked for card values, the order intent id, and provider text. + const run = async (args: unknown = input, context: unknown = ctx()) => { + const output = await cardTool.execute(args as never, context as never); + const text = JSON.stringify(output); + for (const secret of [NUMBER, `"${CVC}"`, "oi_test_secret", "secret provider text"]) expect(text).not.toContain(secret); + return output; + }; + const crossmint = (...responses: [number, unknown][]) => { + const fetcher = vi.fn(); + for (const [status, body] of responses) fetcher.mockResolvedValueOnce(new Response(JSON.stringify(body), { status })); + vi.stubGlobal("fetch", fetcher); + return fetcher; + }; + + beforeEach(() => { + for (const [name, value] of Object.entries(env)) vi.stubEnv(name, value); + vi.mocked(runBrowserOperation).mockClear(); + vi.mocked(checkoutInHostedPage).mockReset(); + }); + afterEach(() => { + vi.unstubAllEnvs(); + vi.unstubAllGlobals(); + }); + + it("asks the person to approve the amount and merchant, and only the requester can", () => { + const approval = cardTool.approval as { prompt: (ctx: unknown) => string; response: (ctx: unknown) => { status: string } }; + expect(approval.prompt({ input })).toBe("Pay 12.49 USD at shop.example with your Crossmint agent card?"); + // The dialog shows the host, never the text the model wrote around it. + expect(approval.prompt({ input: { ...input, merchant: "https://shop.example/checkout?note=test-charge-refunded" } })).toBe( + "Pay 12.49 USD at shop.example with your Crossmint agent card?", + ); + expect(approval.response({ request: { principal }, response: { principal } })).toEqual({ status: "allowed" }); + expect(approval.response({ request: { principal }, response: { principal: { ...principal, principalId: "linq:2" } } })).toMatchObject({ status: "rejected" }); + expect(approval.response({ request: { principal: null }, response: { principal } })).toMatchObject({ status: "rejected" }); + }); + + it("accepts card fields only, so nothing can fail on a missing billing address after the mint", () => { + const schema = cardTool.inputSchema as unknown as { safeParse: (value: unknown) => { success: boolean } }; + expect(schema.safeParse(input).success).toBe(true); + expect(schema.safeParse({ ...input, fields: [...input.fields, { field: "postal_code", selector: "#zip" }] }).success).toBe(false); + expect(schema.safeParse({ ...input, fields: [{ field: "number", selector: "xpath=//input" }] }).success).toBe(false); + }); + + it("answers not_configured, authentication_required, or payment_not_configured before any call", async () => { + const fetcher = crossmint(); + vi.stubEnv("CROSSMINT_CLIENT_API_KEY", ""); + expect(await run()).toMatchObject({ status: "not_configured" }); + vi.stubEnv("CROSSMINT_CLIENT_API_KEY", env.CROSSMINT_CLIENT_API_KEY); + expect(await run(input, ctx(null))).toMatchObject({ status: "error", reason: "authentication_required" }); + vi.stubEnv("CROSSMINT_ORDER_INTENT_ID", ""); + expect(await run()).toMatchObject({ status: "payment_not_configured" }); + vi.stubEnv("CROSSMINT_ORDER_INTENT_ID", env.CROSSMINT_ORDER_INTENT_ID); + vi.stubEnv("CROSSMINT_ALLOWED_MERCHANTS", "https://other.example"); + expect(await run()).toMatchObject({ status: "error", reason: "merchant_not_allowed" }); + vi.stubEnv("CROSSMINT_ALLOWED_MERCHANTS", ""); + vi.stubEnv("CROSSMINT_MAX_COST", "10.00 USD"); + expect(await run()).toMatchObject({ status: "error", reason: "cap_exceeded" }); + expect(fetcher).not.toHaveBeenCalled(); + expect(runBrowserOperation).not.toHaveBeenCalled(); + }); + + it("refuses from the order intent before any browser work or mint", async () => { + const fetcher = crossmint([200, intent({ merchant: { name: "Other", url: "https://other.example", countryCode: "US" } })]); + expect(await run()).toMatchObject({ status: "error", reason: "merchant_mismatch" }); + expect(fetcher).toHaveBeenCalledOnce(); + expect(runBrowserOperation).not.toHaveBeenCalled(); + }); + + it("mints inside the private fill and returns only the fill status", async () => { + const fetcher = crossmint([200, intent()], [201, issued()]); + vi.mocked(checkoutInHostedPage).mockImplementation(async (_page, connection, checkout, origins, getCredentials) => { + expect(connection).toBe("private-connection"); + expect(checkout).toMatchObject({ id: "crossmint_card", amount: 1249, currency: "usd", credential: "card", fields: input.fields, submit: input.submit }); + expect(origins).toEqual(["https://shop.example", "https://pay.example"]); + expect(fetcher).toHaveBeenCalledOnce(); + expect(await getCredentials()).toMatchObject({ card: { number: NUMBER, cvc: CVC } }); + return { id: "crossmint_card", status: "merchant_confirmation_observed", verify_payment: true }; + }); + expect(await run()).toEqual({ status: "merchant_confirmation_observed", verify_payment: true }); + const mint = fetcher.mock.calls[1] as unknown as [string, { headers: Record }]; + expect(mint[1].headers["Idempotency-Key"]).toBe(idempotencyKey("session-cards", "call-1")); + }); + + it("returns the reasons an operator must act on, and maps an interrupted fill", async () => { + crossmint([200, intent()], [409, { error: true, code: "ORDER_INTENT_CVC_RECOLLECTION_REQUIRED", message: "secret provider text" }]); + vi.mocked(checkoutInHostedPage).mockImplementation(async (_page, _url, _input, _origins, getCredentials) => { + await getCredentials(); + throw new Error("must not reach the fill"); + }); + expect(await run()).toMatchObject({ status: "error", reason: "cvc_recollection_required" }); + + crossmint([200, intent()], [201, issued()]); + vi.mocked(checkoutInHostedPage).mockImplementation(async (_page, _url, _input, _origins, getCredentials) => { + await getCredentials(); + throw new Error("Checkout stopped before submission. Check the existing Link request and browser before retrying."); + }); + const stopped = await run(input, ctx(principal, "call-2")); + expect(stopped).toMatchObject({ status: "error", reason: "stopped_before_submission" }); + expect(JSON.stringify(stopped)).not.toContain("Link"); + + crossmint([200, intent()], [201, issued()]); + vi.mocked(checkoutInHostedPage).mockImplementation(async (_page, _url, _input, _origins, getCredentials) => { + await getCredentials(); + throw new Error("Payment requires a private browser lock."); + }); + expect(await run(input, ctx(principal, "call-3"))).toMatchObject({ status: "error", reason: "card_issued_unfinished", message: expect.stringContaining("do not retry") }); + }); + + it("refuses before any mint when the browser lock is not held", async () => { + lock.held = false; + try { + const fetcher = crossmint([200, intent()], [201, issued()]); + vi.mocked(checkoutInHostedPage).mockImplementation(async (_page, _url, _input, _origins, getCredentials) => { + await getCredentials(); + throw new Error("must not reach the fill"); + }); + expect(await run(input, ctx(principal, "call-4"))).toMatchObject({ status: "error", reason: "browser_lock_unavailable", message: expect.stringContaining("no card was issued") }); + expect(fetcher).toHaveBeenCalledOnce(); + } finally { + lock.held = true; + } + }); +}); + +describe("Browser privacy lock with Agent Cards", () => { + afterEach(() => vi.unstubAllEnvs()); + + it("engages for the card path even without Link", async () => { + vi.stubEnv("LINK_CLIENT_ID", ""); + vi.stubEnv("LINK_SANDBOX", ""); + vi.stubEnv("DATABASE_URL", ""); + for (const name of Object.keys(env)) vi.stubEnv(name, ""); + expect(await withBrowserPrivacyLock("session-plain", async () => "unlocked")).toBe("unlocked"); + for (const [name, value] of Object.entries(env)) vi.stubEnv(name, value); + await expect(withBrowserPrivacyLock("session-cards", async () => "unlocked")).rejects.toThrow("Browser payments require DATABASE_URL."); + }); +}); diff --git a/tests/crossmint-setup.test.ts b/tests/crossmint-setup.test.ts new file mode 100644 index 0000000..6239cf9 --- /dev/null +++ b/tests/crossmint-setup.test.ts @@ -0,0 +1,209 @@ +import { createPublicKey, generateKeyPairSync, verify } from "node:crypto"; +import { isValidElement, type ReactElement, type ReactNode } from "react"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { config as proxyConfig, proxy } from "../proxy.js"; +import CrossmintSetupPage from "../app/crossmint/setup/page.js"; +import { approveBudget, refreshToken } from "../app/crossmint/setup/actions.js"; +import { operatorJwks, parseRsaPrivateKey } from "../server/crossmint/operator-jwt.js"; + +const incoming = vi.hoisted(() => ({ headers: new Headers() })); +vi.mock("next/headers", () => ({ headers: async () => incoming.headers })); +vi.mock("../app/crossmint/setup/setup", () => ({ default: function Setup() { return null; } })); + +const { privateKey } = generateKeyPairSync("rsa", { modulusLength: 2048 }); +const password = "a-synthetic-operator-password-of-32-bytes"; +const basic = `Basic ${Buffer.from(`operator:${password}`).toString("base64")}`; +const env = { + BELL_OPERATOR_USERNAME: "operator", + BELL_OPERATOR_PASSWORD: password, + CROSSMINT_SERVER_API_KEY: "sk_unit_test_only", + CROSSMINT_USER_ID: "operator-1", + CROSSMINT_CLIENT_API_KEY: "ck_production_unit_test_only", + CROSSMINT_PROJECT_ID: "project-1", + CROSSMINT_JWT_PRIVATE_KEY: Buffer.from(privateKey.export({ type: "pkcs8", format: "pem" })).toString("base64"), + CROSSMINT_BUYER_PROFILE_ID: "", + CROSSMINT_ORDER_INTENT_ID: "oi_in_use", + BELL_PUBLIC_URL: "https://bell.example", +}; + +const intent = (id: string, expiresAt: string, rails: unknown[] = [{ rail: "spt", provider: "stripe", status: "active" }]) => ({ + orderIntentId: id, + paymentMethodId: "pm_1", + status: "active", + amount: { total: "30.00", spent: "0.00", reserved: "0.00", available: "30.00", currency: "eur" }, + merchant: { name: "Zara", url: "https://www.zara.com", countryCode: "ES" }, + description: "Demo", + expiresAt, + rails, +}); + +function setupProps(node: ReactNode): Record | undefined { + if (Array.isArray(node)) return node.map(setupProps).find(Boolean); + if (!isValidElement<{ children?: ReactNode }>(node)) return undefined; + if (typeof node.type === "function" && node.type.name === "Setup") return (node as ReactElement>).props; + return setupProps(node.props.children); +} + +beforeEach(() => { + for (const [name, value] of Object.entries(env)) vi.stubEnv(name, value); + incoming.headers = new Headers({ host: "bell.example", "x-forwarded-proto": "https" }); +}); +afterEach(() => { + vi.unstubAllEnvs(); + vi.unstubAllGlobals(); +}); + +describe("Crossmint setup access", () => { + it("covers only the Crossmint pages", () => { + expect(proxyConfig.matcher).toEqual(["/crossmint/:path*"]); + }); + + it("asks for the operator's credentials and refuses cross-origin writes", async () => { + const challenge = await proxy(new Request("https://bell.example/crossmint/setup")); + expect(challenge.status).toBe(401); + expect(challenge.headers.get("www-authenticate")).toContain('Basic realm="Bell"'); + const allowed = await proxy(new Request("https://bell.example/crossmint/setup", { headers: { authorization: basic } })); + expect(allowed.headers.get("x-middleware-next")).toBe("1"); + for (const response of [challenge, allowed]) { + expect(response.headers.get("content-security-policy")).toBe("frame-ancestors 'none'"); + expect(response.headers.get("x-frame-options")).toBe("DENY"); + } + const crossOrigin = await proxy(new Request("https://bell.example/crossmint/setup", { method: "POST", headers: { authorization: basic, origin: "https://evil.example" } })); + expect(crossOrigin.status).toBe(403); + }); + + it("checks again in the page and signs nothing for an unauthenticated request", async () => { + const page = await CrossmintSetupPage(); + expect(setupProps(page)).toBeUndefined(); + expect(JSON.stringify(page)).not.toContain("ck_production_unit_test_only"); + }); + + it("refuses actions without the operator's credentials or from another origin, before calling Crossmint", async () => { + const fetcher = vi.fn(); + vi.stubGlobal("fetch", fetcher); + await expect(approveBudget({} as never)).rejects.toThrow("Sign in as the Bell operator"); + incoming.headers.set("authorization", basic); + incoming.headers.set("origin", "https://evil.example"); + await expect(refreshToken()).rejects.toThrow(); + expect(fetcher).not.toHaveBeenCalled(); + }); +}); + +describe("Crossmint setup page", () => { + it("lists budgets, marks the one in use, and gives the browser only the client key", async () => { + incoming.headers.set("authorization", basic); + const fetcher = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + expect(String(url)).toBe("https://www.crossmint.com/api/unstable/order-intents"); + expect(init?.headers).toMatchObject({ "X-API-KEY": "ck_production_unit_test_only", Origin: "https://bell.example" }); + return Response.json([intent("oi_old", "2026-11-03T00:00:00.000Z"), intent("oi_in_use", "2026-11-08T00:00:00.000Z")]); + }); + vi.stubGlobal("fetch", fetcher); + const props = setupProps(await CrossmintSetupPage())!; + expect(props.checks).toMatchObject({ server: { state: "ok" }, operator: { state: "ok" }, token: { state: "ok" } }); + const budgets = props.budgets as { id: string; inUse: boolean; currency: string; merchantHost: string; rails: string[] }[]; + expect(budgets.map((budget) => [budget.id, budget.inUse])).toEqual([["oi_in_use", true], ["oi_old", false]]); + expect(budgets[0]).toMatchObject({ currency: "EUR", merchantHost: "www.zara.com", rails: ["Stripe shared payment token: active"] }); + expect(props.apiKey).toBe("ck_production_unit_test_only"); + expect(props.jwt).toBeUndefined(); + expect(JSON.stringify(props)).not.toContain("sk_unit_test_only"); + }); + + it("signs a ten-minute operator token for the card form on request", async () => { + incoming.headers.set("authorization", basic); + const token = await refreshToken(); + expect(token.ok).toBe(true); + const [header, payload, signature] = (token as { jwt: string }).jwt.split("."); + const claims = JSON.parse(Buffer.from(payload, "base64url").toString()); + expect(claims).toMatchObject({ iss: "project-1", sub: "operator-1", aud: "crossmint.com" }); + expect(claims.exp - claims.iat).toBe(600); + const publicKey = createPublicKey({ key: operatorJwks(parseRsaPrivateKey(env.CROSSMINT_JWT_PRIVATE_KEY)!).keys[0], format: "jwk" }); + expect(verify("sha256", Buffer.from(`${header}.${payload}`), publicKey, Buffer.from(signature, "base64url"))).toBe(true); + }); + + it("shows where to point Crossmint, and no token, when Crossmint rejects Bell's token", async () => { + incoming.headers.set("authorization", basic); + vi.stubGlobal("fetch", vi.fn(async () => Response.json({ message: "Invalid JWT" }, { status: 401 }))); + const props = setupProps(await CrossmintSetupPage())!; + expect(props.checks).toMatchObject({ token: { state: "error", text: expect.stringContaining("rejected Bell's operator token") } }); + expect(props.jwks).toEqual({ url: "https://bell.example/api/crossmint/jwks", issuer: "project-1", loopback: false }); + expect(props.apiKey).toBeUndefined(); + expect(props.jwt).toBeUndefined(); + }); + + it("offers the card network's verification only when paying in Bell's browser is switched on", async () => { + incoming.headers.set("authorization", basic); + const pending = intent("oi_in_use", "2026-12-01T00:00:00.000Z", [{ rail: "agentic-token", provider: "vic", status: "pending_verification", credentialFormats: ["card"] }]); + vi.stubGlobal("fetch", vi.fn(async () => Response.json([{ ...pending, verificationConfig: { allowanceId: "al_1", environment: "production", publicApiKey: "pk_1" } }]))); + const off = setupProps(await CrossmintSetupPage())!; + expect((off.budgets as { verify?: unknown }[])[0].verify).toBeUndefined(); + vi.stubEnv("CROSSMINT_CARD_CHECKOUT", "1"); + const on = setupProps(await CrossmintSetupPage())!; + expect((on.budgets as { verify?: { orderIntentId: string } }[])[0].verify).toMatchObject({ orderIntentId: "oi_in_use", verificationConfig: { allowanceId: "al_1" } }); + }); + + it("names a missing setting instead of calling Crossmint", async () => { + incoming.headers.set("authorization", basic); + vi.stubEnv("CROSSMINT_PROJECT_ID", ""); + const fetcher = vi.fn(); + vi.stubGlobal("fetch", fetcher); + const props = setupProps(await CrossmintSetupPage())!; + expect(props.checks).toMatchObject({ operator: { state: "error", text: expect.stringContaining("CROSSMINT_PROJECT_ID") } }); + expect(props.jwt).toBeUndefined(); + expect(fetcher).not.toHaveBeenCalled(); + }); +}); + +describe("Crossmint budget approval", () => { + const draft = { + paymentMethodId: "pm_1", + idempotencyKey: "2f1c8e7a-5b3d-4c2e-9a1f-0d6b7e8c9a10", + amount: "30.00", + currency: "eur", + days: 7, + description: "Demo", + merchant: { name: "Zara", url: "https://www.zara.com", countryCode: "es" }, + consumer: { email: "person@example.com", countryCode: "es", languageCode: "es-ES" }, + }; + + it("registers the card with the person's email before creating the order intent", async () => { + incoming.headers.set("authorization", basic); + const calls: { method: string; path: string; body?: unknown; key?: string }[] = []; + vi.stubGlobal("fetch", vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + const path = new URL(String(url)).pathname.replace("/api/unstable", ""); + const key = (init?.headers as Record | undefined)?.["Idempotency-Key"]; + calls.push({ method: init?.method ?? "GET", path, ...(init?.body ? { body: JSON.parse(init.body as string) } : {}), ...(key ? { key } : {}) }); + if (init?.method === "GET") return Response.json({ message: "not found" }, { status: 404 }); + if (init?.method === "PUT") return Response.json({ paymentMethodId: "pm_1", rails: [{ rail: "spt", provider: "stripe", status: "enabled" }] }); + return Response.json(intent("oi_new", "2026-11-09T00:00:00.000Z")); + })); + const result = await approveBudget(draft); + expect(result).toMatchObject({ ok: true, budget: { id: "oi_new", currency: "EUR", networkRail: false } }); + expect(calls.map((call) => `${call.method} ${call.path}`)).toEqual([ + "GET /payment-methods/pm_1/order-intent-registration", + "PUT /payment-methods/pm_1/order-intent-registration", + "POST /order-intents", + ]); + expect(calls[1].body).toEqual({ email: "person@example.com", countryCode: "ES", languageCode: "es-ES" }); + expect(calls[2].key).toBe("bell-budget-2f1c8e7a-5b3d-4c2e-9a1f-0d6b7e8c9a10"); + expect(calls[2].body).toMatchObject({ + paymentMethodId: "pm_1", + amount: { value: "30.00", currency: "EUR" }, + merchant: { name: "Zara", url: "https://www.zara.com", countryCode: "ES" }, + description: "Demo", + }); + }); + + it("returns Crossmint's reason to the operator and refuses a merchant without HTTPS before any call", async () => { + incoming.headers.set("authorization", basic); + const fetcher = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => + init?.method === "GET" + ? Response.json({ message: "not found" }, { status: 404 }) + : Response.json({ message: ["A consumer email is required to register this payment method for order intents"] }, { status: 400 }), + ); + vi.stubGlobal("fetch", fetcher); + expect(await approveBudget(draft)).toEqual({ ok: false, message: expect.stringContaining("A consumer email is required") }); + fetcher.mockClear(); + expect(await approveBudget({ ...draft, merchant: { ...draft.merchant, url: "http://www.zara.com" } })).toMatchObject({ ok: false, message: expect.stringContaining("HTTPS") }); + expect(fetcher).not.toHaveBeenCalled(); + }); +}); diff --git a/tests/crossmint.test.ts b/tests/crossmint.test.ts new file mode 100644 index 0000000..95ffd55 --- /dev/null +++ b/tests/crossmint.test.ts @@ -0,0 +1,583 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { + AMOUNT, + answerForm, + assertCheckoutPolicy, + cancelCheckout, + compareAmounts, + createBuyerProfile, + createCheckout, + crossmintConfig, + CrossmintPolicyError, + CrossmintRequestError, + CrossmintSetupError, + declineRequest, + getBuyerProfile, + getCheckout, + isCrossmintConfigured, + payWithOrderIntent, + projectCheckout, + projectProgress, + waitForCheckout, + type CheckoutSnapshot, +} from "../server/crossmint/client.js"; +import { assertPaymentMatches, PaymentMismatchError } from "../server/crossmint/payment.js"; +import { assertSessionCheckout, rememberCheckout, sessionCheckout } from "../server/crossmint/runs.js"; +import checkoutTool from "../agent/tools/crossmint_checkout.js"; +import payTool from "../agent/tools/crossmint_pay.js"; +import { payee } from "../agent/lib/crossmint.js"; + +const config = { + apiKey: "sk_unit_test_only", + userId: "operator-1", + baseUrl: "https://www.crossmint.com/api/unstable", + allowedMerchants: [] as string[], + orderIntentId: "oi_test_secret", +}; + +const snapshot = (overrides: Record) => ({ + runId: "run_1", + status: "running", + revision: 1, + createdAt: "2026-10-28T12:00:00.000Z", + browser: { embedUrl: "https://browser.example/secret", permissions: ["read"] }, + input: { request: { startUrl: "https://shop.example/p/1" }, constraints: { maxCost: { amount: "20.00", currency: "USD" } } }, + requiredAction: null, + ...overrides, +}); + +const paymentRequest = (amount = "12.49", currency = "USD", url = "https://shop.example", method: Record = { method: "card" }) => + snapshot({ + status: "awaiting_input", + requiredAction: { + messageId: "m", + requestId: "req_pay", + type: "input_response", + request: { + question: `Authorize a card payment of ${amount} ${currency}.`, + expiresAt: "2026-10-28T12:10:00.000Z", + interaction: { + kind: "payment", + purpose: "checkout_payment", + amount: { kind: "exact", value: amount, currency }, + merchant: { name: "Example Shop", url, countryCode: "US" }, + ...method, + }, + }, + }, + }); + +const formRequest = (requestId: string, fields: unknown[]) => + snapshot({ status: "awaiting_input", requiredAction: { requestId, request: { question: "Which size?", interaction: { kind: "form", fields } } } }); + +describe("Crossmint configuration", () => { + it("is optional until used", () => { + expect(isCrossmintConfigured({})).toBe(false); + expect(isCrossmintConfigured({ CROSSMINT_SERVER_API_KEY: "sk_x", CROSSMINT_USER_ID: "u" })).toBe(true); + }); + + it("names the missing or invalid setting without logging values", () => { + const base = { CROSSMINT_SERVER_API_KEY: "sk_x", CROSSMINT_USER_ID: "u" }; + expect(() => crossmintConfig({})).toThrow(CrossmintSetupError); + expect(() => crossmintConfig({})).toThrow("CROSSMINT_SERVER_API_KEY"); + expect(() => crossmintConfig({ ...base, CROSSMINT_SERVER_API_KEY: "ck_client_key" })).toThrow("CROSSMINT_SERVER_API_KEY"); + expect(() => crossmintConfig({ ...base, CROSSMINT_API_BASE_URL: "http://insecure.example" })).toThrow("CROSSMINT_API_BASE_URL"); + expect(() => crossmintConfig({ ...base, CROSSMINT_MAX_COST: "50 dollars" })).toThrow("CROSSMINT_MAX_COST"); + expect(() => crossmintConfig({ ...base, CROSSMINT_MAX_COST: "0.00 EUR" })).toThrow("CROSSMINT_MAX_COST"); + expect(() => crossmintConfig({ ...base, CROSSMINT_ALLOWED_MERCHANTS: "https://shop.example/path" })).toThrow("CROSSMINT_ALLOWED_MERCHANTS"); + expect(() => crossmintConfig({ ...base, CROSSMINT_ALLOWED_MERCHANTS: "http://shop.example" })).toThrow("CROSSMINT_ALLOWED_MERCHANTS"); + + const parsed = crossmintConfig({ + ...base, + CROSSMINT_MAX_COST: "50.00 EUR", + CROSSMINT_ALLOWED_MERCHANTS: "https://shop.example, https://other.example", + CROSSMINT_BUYER_PROFILE_ID: "bp_1", + }); + expect(parsed).toMatchObject({ + baseUrl: "https://www.crossmint.com/api/unstable", + maxCost: { amount: "50.00", currency: "EUR" }, + allowedMerchants: ["https://shop.example", "https://other.example"], + buyerProfileId: "bp_1", + }); + expect(parsed.orderIntentId).toBeUndefined(); + }); +}); + +describe("Crossmint checkout policy", () => { + it("accepts the amounts Crossmint accepts", () => { + for (const value of ["20", "20.00", "0.50", "999999999999999.99"]) expect(AMOUNT.test(value)).toBe(true); + for (const value of ["0", "0.00", "020", "1.234", "-1", "1,00", ""]) expect(AMOUNT.test(value)).toBe(false); + }); + + it("compares decimal amounts without floating point, at six decimals", () => { + expect(compareAmounts("20", "20.00")).toBe(0); + expect(compareAmounts("19.99", "20.00")).toBe(-1); + expect(compareAmounts("20.01", "20.00")).toBe(1); + expect(compareAmounts("0.1", "0.10")).toBe(0); + expect(compareAmounts("12.49", "12.491")).toBe(-1); + }); + + it("allows any merchant and any cap when no policy is set", () => { + expect(() => assertCheckoutPolicy("https://anything.example/p", { amount: "9999.00", currency: "USD" }, config)).not.toThrow(); + }); + + it("refuses merchants outside the allowlist before any request is made", () => { + const policy = { ...config, allowedMerchants: ["https://shop.example"] }; + expect(() => assertCheckoutPolicy("https://shop.example/p/1", { amount: "1.00", currency: "USD" }, policy)).not.toThrow(); + for (const url of ["https://evil.example/p", "http://shop.example/p", "https://shop.example.evil.example/p", "https://user:pw@shop.example/p", "not a url"]) { + expect(() => assertCheckoutPolicy(url, { amount: "1.00", currency: "USD" }, policy)).toThrow(CrossmintPolicyError); + } + }); + + it("refuses caps above the operator ceiling or in another currency", () => { + const policy = { ...config, maxCost: { amount: "50.00", currency: "EUR" } }; + expect(() => assertCheckoutPolicy("https://shop.example", { amount: "50.00", currency: "EUR" }, policy)).not.toThrow(); + expect(() => assertCheckoutPolicy("https://shop.example", { amount: "50.01", currency: "EUR" }, policy)).toThrow("operator ceiling"); + expect(() => assertCheckoutPolicy("https://shop.example", { amount: "1.00", currency: "USD" }, policy)).toThrow("limited to EUR"); + }); + + it("stops createCheckout at the policy, so a refused run is never billed", async () => { + const fetcher = vi.fn(); + await expect( + createCheckout( + { startUrl: "https://evil.example/p", task: "x", maxCost: { amount: "1.00", currency: "USD" } }, + { config: { ...config, allowedMerchants: ["https://shop.example"] }, fetch: fetcher }, + ), + ).rejects.toThrow(CrossmintPolicyError); + expect(fetcher).not.toHaveBeenCalled(); + }); +}); + +describe("Crossmint client", () => { + it("creates a checkout with the documented body and headers", async () => { + const fetcher = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + expect(String(url)).toBe("https://www.crossmint.com/api/unstable/agent-checkouts"); + expect(init?.method).toBe("POST"); + expect(init?.redirect).toBe("error"); + expect(init?.headers).toMatchObject({ "X-API-KEY": config.apiKey, "x-crossmint-user-id": config.userId, "Content-Type": "application/json" }); + expect(JSON.parse(init!.body as string)).toEqual({ + request: { startUrl: "https://shop.example/p/1", task: "One sticker pack" }, + constraints: { maxCost: { amount: "20.00", currency: "USD" } }, + buyerProfileId: "bp_1", + browser: { location: { type: "country", countryCode: "ES" } }, + }); + return Response.json({ runId: "run_1" }); + }); + await expect( + createCheckout( + { startUrl: "https://shop.example/p/1", task: "One sticker pack", maxCost: { amount: "20.00", currency: "USD" }, countryCode: "ES" }, + { config: { ...config, buyerProfileId: "bp_1" }, fetch: fetcher }, + ), + ).resolves.toEqual({ runId: "run_1" }); + }); + + it("answers a form with a fresh message id and the submit shape", async () => { + const fetcher = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + expect(String(url)).toBe("https://www.crossmint.com/api/unstable/agent-checkouts/run_1/messages"); + const body = JSON.parse(init!.body as string); + expect(body.id).toMatch(/^bell_/); + expect(body.parts).toEqual([ + { type: "input_response", requestId: "req_1", action: "submit", response: { kind: "form", answers: { email: "ada@example.com", size: "M" } } }, + ]); + return Response.json({ messageId: "msg_1", status: "accepted" }, { status: 202 }); + }); + await answerForm("run_1", "req_1", { email: "ada@example.com", size: "M" }, { config, fetch: fetcher }); + expect(fetcher).toHaveBeenCalledOnce(); + }); + + it("pays with the server-side order intent only", async () => { + const fetcher = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { + const body = JSON.parse(init!.body as string); + expect(body.parts[0]).toEqual({ type: "input_response", requestId: "req_pay", action: "submit", response: { kind: "payment", orderIntentId: "oi_test_secret" } }); + return Response.json({ messageId: "msg_2", status: "accepted" }, { status: 202 }); + }); + await payWithOrderIntent("run_1", "req_pay", { config, fetch: fetcher }); + await expect(payWithOrderIntent("run_1", "req_pay", { config: { ...config, orderIntentId: undefined }, fetch: fetcher })).rejects.toThrow("CROSSMINT_ORDER_INTENT_ID"); + expect(fetcher).toHaveBeenCalledOnce(); + }); + + it("declines and cancels through the documented endpoints and accepts empty 202 bodies", async () => { + const calls: string[] = []; + const fetcher = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + calls.push(`${init?.method} ${String(url).replace(config.baseUrl, "")}`); + if (init?.body) expect(JSON.parse(init.body as string).parts[0]).toEqual({ type: "input_response", action: "decline", requestId: "req_1" }); + return new Response(null, { status: 202 }); + }); + await declineRequest("run_1", "req_1", { config, fetch: fetcher }); + await cancelCheckout("run_1", { config, fetch: fetcher }); + expect(calls).toEqual(["POST /agent-checkouts/run_1/messages", "POST /agent-checkouts/run_1/cancel"]); + }); + + it("does not expose provider error bodies", async () => { + const run = (status: number) => getCheckout("run_1", { config, fetch: async () => new Response("private merchant data", { status }) }); + await expect(run(401)).rejects.toThrow(/^Crossmint rejected the API key or its scopes\.$/); + await expect(run(403)).rejects.toThrow(/^Crossmint rejected the API key or its scopes\.$/); + await expect(run(404)).rejects.toThrow(/^Crossmint has no checkout with that id for this buyer\.$/); + await expect(run(429)).rejects.toThrow(/rate limited/); + await expect(run(500)).rejects.toThrow(/^Crossmint returned HTTP 500\.$/); + await expect(getCheckout("run_1", { config, fetch: async () => new Response("private") })).rejects.toThrow(/^Crossmint returned an unexpected response\.$/); + await expect( + getCheckout("run_1", { config, fetch: async () => { throw new Error("private request details"); } }), + ).rejects.toThrow(/^Crossmint request failed\. Check connectivity and retry\.$/); + }); + + it("does not call the API after cancellation", async () => { + const fetcher = vi.fn(); + await expect(getCheckout("run_1", { config, fetch: fetcher, signal: AbortSignal.abort() })).rejects.toThrow(); + expect(fetcher).not.toHaveBeenCalled(); + }); +}); + +describe("Crossmint snapshot projection", () => { + it("drops browser URLs, the echoed input, and unknown fields", () => { + const projected = projectCheckout(snapshot({ secret: "x" })); + expect(projected).toEqual({ runId: "run_1", status: "running", revision: 1, requiredAction: null, result: null, failureReason: null }); + expect(JSON.stringify(projected)).not.toContain("browser.example"); + }); + + it("projects form fields with Crossmint's input kinds, choice options, and protected handling", () => { + const projected = projectCheckout( + snapshot({ + status: "awaiting_input", + requiredAction: { + messageId: "m", + requestId: "req_1", + type: "input_response", + request: { + question: "Which size?", + expiresAt: "2026-10-28T12:10:00.000Z", + interaction: { + kind: "form", + fields: [ + { + key: "size", + label: "Size", + required: true, + handling: "standard", + input: { + kind: "choice", + selection: { kind: "one" }, + options: [ + { value: "", label: "Choose a size", placeholder: true, disabled: false, selected: false }, + { value: "M", label: "Medium", placeholder: false, disabled: false, selected: false }, + { value: "XL", label: "XL", placeholder: false, disabled: true, selected: false }, + ], + }, + }, + { key: "quantity", label: "Quantity", required: false, handling: "standard", input: { kind: "integer" } }, + { key: "otp", label: "Code", required: true, handling: "protected", input: { kind: "text", display: "masked", autoComplete: "one-time-code" } }, + { label: "no key", handling: "standard", input: { kind: "text" } }, + ], + }, + }, + }, + }), + ); + expect(projected.requiredAction).toEqual({ + requestId: "req_1", + question: "Which size?", + expiresAt: "2026-10-28T12:10:00.000Z", + interaction: { + kind: "form", + fields: [ + { key: "size", label: "Size", required: true, handling: "standard", kind: "choice", options: [{ value: "M", label: "Medium" }], selection: "one" }, + { key: "quantity", label: "Quantity", required: false, handling: "standard", kind: "integer" }, + { key: "otp", label: "Code", required: true, handling: "protected", kind: "text" }, + ], + }, + }); + }); + + it("projects a payment request to method, amount, and merchant only", () => { + const raw = paymentRequest(); + (raw.requiredAction as unknown as { request: { interaction: Record } }).request.interaction.card = { number: "4242" }; + const projected = projectCheckout(raw); + expect(projected.requiredAction?.interaction).toEqual({ + kind: "payment", + method: "card", + amount: { kind: "exact", value: "12.49", currency: "USD" }, + merchant: { name: "Example Shop", url: "https://shop.example", countryCode: "US" }, + }); + expect(JSON.stringify(projected)).not.toContain("4242"); + const klarna = projectCheckout(paymentRequest("12.49", "USD", "https://shop.example", { method: "klarna", authorizationUrl: "https://uc.example/pay/secret" })); + expect(klarna.requiredAction?.interaction).toMatchObject({ kind: "payment", method: "klarna" }); + expect(JSON.stringify(klarna)).not.toContain("uc.example"); + }); + + it("keeps receipt metadata on success and codes on blocked or failed runs", () => { + expect( + projectCheckout( + snapshot({ + status: "succeeded", + result: { outcome: "succeeded", summary: "Ordered one sticker pack.", purchase: { kind: "receipt_captured", receipt: { total: { amount: "12.49", currency: "USD" }, merchantOrderId: "A-100" } } }, + }), + ).result, + ).toEqual({ outcome: "succeeded", summary: "Ordered one sticker pack.", purchase: { kind: "receipt_captured", receipt: { total: { amount: "12.49", currency: "USD" }, merchantOrderId: "A-100" } } }); + expect(projectCheckout(snapshot({ status: "succeeded", result: { outcome: "succeeded", summary: "Confirmed.", purchase: { kind: "confirmed_without_receipt" } } })).result) + .toEqual({ outcome: "succeeded", summary: "Confirmed.", purchase: { kind: "confirmed_without_receipt" } }); + expect(projectCheckout(snapshot({ status: "blocked", result: { outcome: "blocked", code: "merchant.payment_declined", summary: "Declined." } })).result) + .toEqual({ outcome: "blocked", code: "merchant.payment_declined", summary: "Declined." }); + expect(projectCheckout(snapshot({ status: "failed", reason: "cost_limit" })).failureReason).toBe("cost_limit"); + }); + + it("rejects malformed snapshots", () => { + expect(() => projectCheckout({ status: "running" })).toThrow(CrossmintRequestError); + expect(() => projectCheckout(snapshot({ status: "exploded" }))).toThrow(CrossmintRequestError); + expect(() => projectCheckout("not json")).toThrow(CrossmintRequestError); + }); +}); + +describe("Crossmint payment cross-check", () => { + const record = { runId: "run_1", maxCost: { amount: "20.00", currency: "USD" }, principalId: "linq:1" }; + const approved = { requestId: "req_pay", amount: "12.49", currency: "USD", merchant: "shop.example" }; + const live = (raw: Record): CheckoutSnapshot => projectCheckout(raw); + + it("accepts a payment whose amount, currency, merchant, and cap all agree", () => { + expect(assertPaymentMatches(approved, live(paymentRequest()), record)).toEqual({ amount: { amount: "12.49", currency: "USD" }, merchant: "shop.example" }); + expect(assertPaymentMatches({ ...approved, merchant: "https://shop.example/checkout" }, live(paymentRequest()), record).merchant).toBe("shop.example"); + }); + + it.each([ + ["no_payment_request", approved, snapshot({ status: "running" })], + ["request_changed", { ...approved, requestId: "req_old" }, paymentRequest()], + ["unsupported_method", approved, paymentRequest("12.49", "USD", "https://shop.example", { method: "klarna", authorizationUrl: "https://uc.example/pay" })], + ["unsupported_amount", approved, paymentRequest("12.49", "USD", "https://shop.example", { method: "card", amount: { kind: "maximum", value: "12.49", currency: "USD" } })], + ["currency_mismatch", { ...approved, currency: "EUR" }, paymentRequest()], + ["amount_mismatch", { ...approved, amount: "12.48" }, paymentRequest()], + ["merchant_mismatch", { ...approved, merchant: "evil.example" }, paymentRequest()], + ["cap_exceeded", { ...approved, amount: "20.01" }, paymentRequest("20.01")], + ] as const)("refuses on %s", (reason, input, raw) => { + let caught: unknown; + try { + assertPaymentMatches(input, live(raw), record); + } catch (error) { + caught = error; + } + expect(caught).toBeInstanceOf(PaymentMismatchError); + expect((caught as PaymentMismatchError).reason).toBe(reason); + }); +}); + +describe("Crossmint polling", () => { + it("waits through running states, skips an answered request, and stops on new input or a terminal state", async () => { + const sequence = [ + snapshot({ status: "running", revision: 1 }), + formRequest("answered", []), + { ...formRequest("req_new", []), revision: 3 }, + ]; + const fetcher = vi.fn(async () => Response.json(sequence.shift() ?? sequence.at(-1))); + const result = await waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, skipRequestId: "answered" }); + expect(result.status).toBe("awaiting_input"); + expect(result.requiredAction?.requestId).toBe("req_new"); + expect(fetcher).toHaveBeenCalledTimes(3); + }); + + it("returns the latest snapshot at the timeout instead of hanging", async () => { + const fetcher = vi.fn(async () => Response.json(snapshot({ status: "running" }))); + const result = await waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, timeoutMs: 10 }); + expect(result.status).toBe("running"); + expect(fetcher.mock.calls.length).toBeGreaterThan(1); + }); + + it("stops polling when the turn is cancelled", async () => { + const controller = new AbortController(); + const fetcher = vi.fn(async () => { + controller.abort(); + return Response.json(snapshot({ status: "running" })); + }); + await expect(waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 50, signal: controller.signal })).rejects.toThrow(); + expect(fetcher).toHaveBeenCalledOnce(); + }); +}); + +describe("Crossmint run registry", () => { + it("scopes checkouts to the conversation that started them and keeps the cap", () => { + const record = { runId: "run_a", maxCost: { amount: "20.00", currency: "USD" }, principalId: "linq:1" }; + rememberCheckout("session-a", record); + expect(sessionCheckout("session-a", "run_a")).toEqual(record); + expect(sessionCheckout("session-b", "run_a")).toBeUndefined(); + expect(assertSessionCheckout("session-a", "run_a")).toEqual(record); + expect(() => assertSessionCheckout("session-b", "run_a")).toThrow("did not start that checkout"); + }); +}); + +describe("Crossmint tools", () => { + const principal = { principalId: "linq:1", principalType: "user", authenticator: "linq-message", attributes: {} }; + const ctx = (auth: typeof principal | null, id = "session-tools") => ({ session: { id, auth: { current: auth, initiator: auth } }, abortSignal: new AbortController().signal }); + const configure = () => { + vi.stubEnv("CROSSMINT_SERVER_API_KEY", "sk_unit_test_only"); + vi.stubEnv("CROSSMINT_USER_ID", "operator-1"); + vi.stubEnv("CROSSMINT_ORDER_INTENT_ID", ""); + }; + afterEach(() => vi.unstubAllEnvs()); + + it("answer not_configured until the variables are set", async () => { + vi.stubEnv("CROSSMINT_SERVER_API_KEY", ""); + vi.stubEnv("CROSSMINT_USER_ID", ""); + expect(await checkoutTool.execute({ action: "status", runId: "run_1" }, ctx(principal) as never)).toMatchObject({ status: "not_configured" }); + expect(await payTool.execute({ runId: "run_1", requestId: "req_pay", amount: "12.49", currency: "USD", merchant: "shop.example" }, ctx(principal) as never)).toMatchObject({ status: "not_configured" }); + }); + + it("let only the requesting principal approve a payment", () => { + const policy = (payTool.approval as { response: (ctx: unknown) => { status: string } }).response; + const other = { ...principal, principalId: "linq:2" }; + expect(policy({ request: { principal }, response: { principal } })).toEqual({ status: "allowed" }); + expect(policy({ request: { principal }, response: { principal: other } })).toMatchObject({ status: "rejected" }); + expect(policy({ request: { principal: null }, response: { principal } })).toMatchObject({ status: "rejected" }); + }); + + it("refuse protected form fields before anything is sent", async () => { + configure(); + const fetcher = vi.fn(async () => Response.json(formRequest("req_1", [{ key: "otp", label: "Code", required: true, handling: "protected", input: { kind: "text" } }]))); + vi.stubGlobal("fetch", fetcher); + rememberCheckout("session-tools", { runId: "run_1", maxCost: { amount: "20.00", currency: "USD" }, principalId: "linq:1" }); + expect(await checkoutTool.execute({ action: "answer", runId: "run_1", requestId: "req_1", answers: { otp: "123456" } }, ctx(principal) as never)).toMatchObject({ status: "error", reason: "protected_field" }); + expect(fetcher).toHaveBeenCalledOnce(); + await expect(Promise.resolve(checkoutTool.execute({ action: "status", runId: "run_1" }, ctx(principal, "session-other") as never))).rejects.toThrow("did not start that checkout"); + }); + + it("stop at payment_not_configured after the cross-check when no order intent is set", async () => { + configure(); + const fetcher = vi.fn(async () => Response.json(paymentRequest())); + vi.stubGlobal("fetch", fetcher); + rememberCheckout("session-tools", { runId: "run_1", maxCost: { amount: "20.00", currency: "USD" }, principalId: "linq:1" }); + const input = { runId: "run_1", requestId: "req_pay", amount: "12.49", currency: "USD", merchant: "shop.example" }; + expect(await payTool.execute(input, ctx(null) as never)).toMatchObject({ status: "error", reason: "authentication_required" }); + expect(await payTool.execute(input, ctx({ ...principal, principalId: "linq:2" }) as never)).toMatchObject({ status: "error", reason: "principal_mismatch" }); + expect(await payTool.execute({ ...input, amount: "12.48" }, ctx(principal) as never)).toMatchObject({ status: "error", reason: "amount_mismatch" }); + expect(await payTool.execute(input, ctx(principal) as never)).toEqual({ + status: "payment_not_configured", + runId: "run_1", + requestId: "req_pay", + hint: expect.stringContaining("No order intent"), + }); + expect(fetcher.mock.calls.every((call) => (call as unknown[])[1] === undefined || ((call as unknown[])[1] as RequestInit).method === "GET")).toBe(true); + }); +}); + +describe("Crossmint progress", () => { + const activity = (id: string, createdAt: string, kinds: string[], revision = 1) => ({ + id, + revision, + role: "assistant", + createdAt, + parts: [{ type: "activity", status: "running", operations: kinds.map((kind) => ({ kind, count: 1 })) }], + }); + const progressText = (id: string, createdAt: string, text: string) => ({ id, revision: 1, role: "assistant", createdAt, parts: [{ type: "progress", text }] }); + + it("maps the latest activity to a fixed stage, in createdAt order and at the latest revision", () => { + const messages = [ + activity("m2", "2026-11-02T12:00:02Z", ["apply_buyer_information", "fill"]), + activity("m1", "2026-11-02T12:00:01Z", ["navigate"]), + activity("m2", "2026-11-02T12:00:02Z", ["apply_payment"], 2), + { id: "u1", revision: 1, role: "user", createdAt: "2026-11-02T12:00:03Z", parts: [{ type: "activity", operations: [{ kind: "navigate" }] }] }, + ]; + expect(projectProgress(messages)).toEqual({ stage: "Applying the payment" }); + expect(projectProgress([activity("m1", "2026-11-02T12:00:01Z", ["click", "scroll"])])).toEqual({ stage: "Working through the store's checkout" }); + expect(projectProgress([])).toBeUndefined(); + }); + + it("never passes on Crossmint's own progress text, which can name the buyer", () => { + const messages = [ + activity("m1", "2026-11-02T12:00:01Z", ["lookup_product"]), + progressText("p1", "2026-11-02T12:00:02Z", "Filling shipping for Ada Lovelace, Calle Mayor 1, 28013 Madrid"), + ]; + expect(projectProgress(messages)).toEqual({ stage: "Finding the product" }); + expect(projectProgress([progressText("p1", "2026-11-02T12:00:02Z", "Opening the store")])).toBeUndefined(); + }); + + it("returns early with progress once the stage changes, but not before the minimum wait", async () => { + const fetcher = vi.fn(async (url: string | URL | Request) => + String(url).includes("/messages") + ? Response.json({ data: [activity("m1", "2026-11-02T12:00:01Z", ["apply_buyer_information"])], nextCursor: null }) + : Response.json(snapshot({ status: "running" })), + ); + const early = await waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, timeoutMs: 1_000, progressSince: null }); + expect(early).toMatchObject({ status: "running", progress: { stage: "Filling in the delivery details" } }); + const unchanged = await waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, timeoutMs: 20, progressSince: "Filling in the delivery details" }); + expect(unchanged.progress).toEqual({ stage: "Filling in the delivery details" }); + const started = Date.now(); + await waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, timeoutMs: 1_000, progressSince: "Opening the store", minProgressMs: 60 }); + expect(Date.now() - started).toBeGreaterThanOrEqual(55); + }); + + it("rethrows a cancellation that lands during a progress read", async () => { + const controller = new AbortController(); + const fetcher = vi.fn(async (url: string | URL | Request) => { + if (String(url).includes("/messages")) { + controller.abort(); + throw new Error("aborted"); + } + return Response.json(snapshot({ status: "running" })); + }); + await expect(waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, timeoutMs: 1_000, progressSince: null, signal: controller.signal })).rejects.toThrow(); + }); + + it("never lets a failed progress read stop the wait, and never adds progress unless asked", async () => { + const fetcher = vi.fn(async (url: string | URL | Request) => + String(url).includes("/messages") ? new Response("nope", { status: 500 }) : Response.json(snapshot({ status: "running" })), + ); + const result = await waitForCheckout("run_1", { config, fetch: fetcher, intervalMs: 1, timeoutMs: 10, progressSince: null }); + expect(result.status).toBe("running"); + expect(result.progress).toBeUndefined(); + const plain = vi.fn(async () => Response.json(snapshot({ status: "running" }))); + expect((await waitForCheckout("run_1", { config, fetch: plain, intervalMs: 1, timeoutMs: 5 })).progress).toBeUndefined(); + expect(plain.mock.calls.every((call) => !String((call as unknown[])[0]).includes("/messages"))).toBe(true); + }); +}); + +describe("Crossmint buyer profiles", () => { + const profile = { + id: "bp_1", + label: "Bell", + name: { first: "Ada", last: "Lovelace" }, + contact: { email: "ada@example.com", phone: "+34600000000" }, + shipping: { addressLines: ["Calle Mayor 1"], locality: "Madrid", countryCode: "ES", administrativeAreaCode: "ES-M", postalCode: "28013" }, + createdAt: "2026-11-02T12:00:00Z", + }; + + it("creates and reads a profile with the server key and the operator id", async () => { + const fetcher = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + expect(init?.headers).toMatchObject({ "X-API-KEY": config.apiKey, "x-crossmint-user-id": config.userId }); + if (init?.method === "POST") { + expect(String(url)).toBe("https://www.crossmint.com/api/unstable/agent-checkouts/buyer-profiles"); + expect(JSON.parse(init.body as string)).toEqual({ label: profile.label, name: profile.name, contact: profile.contact, shipping: profile.shipping }); + } else { + expect(String(url)).toBe("https://www.crossmint.com/api/unstable/agent-checkouts/buyer-profiles/bp_1"); + } + return Response.json(profile); + }); + const input = { label: profile.label, name: profile.name, contact: profile.contact, shipping: profile.shipping }; + const created = await createBuyerProfile(input, { config, fetch: fetcher }); + expect(created).toEqual({ id: "bp_1", label: "Bell", name: profile.name, contact: profile.contact, shipping: profile.shipping }); + await expect(getBuyerProfile("bp_1", { config, fetch: fetcher })).resolves.toEqual(created); + }); + + it("rejects a profile without a shipping address", async () => { + const fetcher = vi.fn(async () => Response.json({ id: "bp_1", shipping: { addressLines: [] } })); + await expect(getBuyerProfile("bp_1", { config, fetch: fetcher })).rejects.toThrow(CrossmintRequestError); + }); +}); + +describe("Crossmint payment store name", () => { + it("refuses when the store name in the approval is not Crossmint's", () => { + const record = { runId: "run_1", maxCost: { amount: "20.00", currency: "USD" }, principalId: "linq:1" }; + const live = projectCheckout(paymentRequest()); + const approved = { requestId: "req_pay", amount: "12.49", currency: "USD", merchant: "shop.example" }; + expect(() => assertPaymentMatches({ ...approved, merchantName: "example shop " }, live, record)).not.toThrow(); + expect(() => assertPaymentMatches({ ...approved, merchantName: "Zara" }, live, record)).toThrow(PaymentMismatchError); + expect(() => assertPaymentMatches({ ...approved, merchantName: "Example Shop: test charge, refunded" }, live, record)).toThrow("store name"); + }); +}); + +describe("Crossmint payment approval wording", () => { + it("names the payee by store name and host, and never shows ids", () => { + expect(payee({ merchant: "https://payments.zara.com/", merchantName: "Zara" })).toBe("Zara (payments.zara.com)"); + expect(payee({ merchant: "shop.example" })).toBe("shop.example"); + expect(payee({ merchant: "https://shop.example", merchantName: "shop.example" })).toBe("shop.example"); + const prompt = (payTool.approval as unknown as { prompt: (ctx: { input: Record }) => string }).prompt; + expect(prompt({ input: { runId: "run_1", requestId: "req_pay", amount: "16.90", currency: "EUR", merchant: "https://payments.zara.com/", merchantName: "Zara" } })).toBe( + "Pay 16.90 EUR at Zara (payments.zara.com) with your saved card?", + ); + }); +});