From 8b6106b2c00dbc1ed3ffa4a223723eea6ce5dcb4 Mon Sep 17 00:00:00 2001 From: Alejandro Dopico Date: Wed, 28 Oct 2026 13:30:18 -0500 Subject: [PATCH 1/4] Add Crossmint Agent Checkouts with approved payments Two tools let Bell buy through Crossmint Agent Checkouts: crossmint_checkout starts a run from a product URL, a plain-language task and a spending cap, answers form questions and declines or cancels; crossmint_pay settles the payment request with the operator's order intent. Payment goes through Eve's tool approval rather than a confirmation in chat. crossmint_pay is declared with approval: always(), the prompt shows the amount, currency and merchant the model put in the call, and after approval the server compares those with the live Crossmint request and with the cap the run was created under before paying. Payments need an authenticated sender, and only the requesting principal can approve. Operator policy is checked before a run is created, so a refused request is never billed: an optional per-checkout ceiling (CROSSMINT_MAX_COST) and an optional merchant allowlist (CROSSMINT_ALLOWED_MERCHANTS). A saved buyer profile (CROSSMINT_BUYER_PROFILE_ID) lets checkouts skip shipping and contact questions. The API key, buyer id, buyer profile and order intent id stay on the server. Each snapshot is projected to a metadata allowlist before Eve can persist it, and a conversation can only act on runs it started in this process. Link, the browser runtime and the hooks are unchanged; with the Crossmint variables unset both tools return not_configured. --- .env.example | 11 + README.md | 1 + agent/instructions.md | 10 + agent/tools/crossmint_checkout.ts | 181 +++++++++ agent/tools/crossmint_pay.ts | 123 ++++++ docs/crossmint.md | 133 +++++++ docs/repository.md | 1 + server/crossmint/client.ts | 622 ++++++++++++++++++++++++++++++ server/crossmint/payment.ts | 91 +++++ server/crossmint/runs.ts | 41 ++ tests/crossmint.test.ts | 367 ++++++++++++++++++ 11 files changed, 1581 insertions(+) create mode 100644 agent/tools/crossmint_checkout.ts create mode 100644 agent/tools/crossmint_pay.ts create mode 100644 docs/crossmint.md create mode 100644 server/crossmint/client.ts create mode 100644 server/crossmint/payment.ts create mode 100644 server/crossmint/runs.ts create mode 100644 tests/crossmint.test.ts diff --git a/.env.example b/.env.example index dcd6a48..fcdc4a0 100644 --- a/.env.example +++ b/.env.example @@ -66,3 +66,14 @@ LINK_TOKEN_ENCRYPTION_KEY= # Exact trusted checkout/frame origins per approved merchant (JSON object). LINK_CHECKOUT_ORIGINS={} + +# Optional Crossmint Agent Checkouts. Production server key (sk_) with agent-checkouts.* scopes. +# See docs/crossmint.md. Leave unset to keep the tools disabled. +CROSSMINT_SERVER_API_KEY= +CROSSMINT_USER_ID= +# The operator's approved order intent id. Required only to pay; never shown to the model. +CROSSMINT_ORDER_INTENT_ID= +# Optional saved buyer profile, per-checkout ceiling ("50.00 EUR"), and exact merchant origins. +CROSSMINT_BUYER_PROFILE_ID= +CROSSMINT_MAX_COST= +CROSSMINT_ALLOWED_MERCHANTS= diff --git a/README.md b/README.md index f7457b7..ab9c12b 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 | Checkout at any merchant under a spending cap, paid after the person approves the exact total | [Agent checkouts](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..b27068f 100644 --- a/agent/instructions.md +++ b/agent/instructions.md @@ -38,3 +38,13 @@ 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. Start with the product URL, the +request, and the user's spending cap. Answer form questions from what the user said; never fill +protected fields. At a payment request, call crossmint_pay with the amount, currency, and merchant +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. diff --git a/agent/tools/crossmint_checkout.ts b/agent/tools/crossmint_checkout.ts new file mode 100644 index 0000000..fd94ca5 --- /dev/null +++ b/agent/tools/crossmint_checkout.ts @@ -0,0 +1,181 @@ +import { defineTool, toolOutput } from "eve/tools"; +import { z } from "zod"; + +import { + answerForm, + cancelCheckout, + createCheckout, + CrossmintPolicyError, + CrossmintRequestError, + CrossmintSetupError, + declineRequest, + getCheckout, + isCrossmintConfigured, + waitForCheckout, + type CheckoutSnapshot, +} from "../../server/crossmint/client"; +import { assertSessionCheckout, rememberCheckout } from "../../server/crossmint/runs"; + +const maxCost = z.object({ + amount: z + .string() + .regex(/^\d+(\.\d{1,2})?$/, "Decimal string such as 20.00") + .describe("Spending cap including shipping and tax, as a decimal string."), + currency: z.string().length(3).toUpperCase().describe("ISO 4217 code, such as USD or EUR."), +}); + +const runId = z.string().min(1).max(200); +const requestId = z.string().min(1).max(200); + +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, + merchantGuidance: z + .string() + .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. Protected fields cannot be answered here."), + }), + z.object({ action: z.literal("decline"), runId, requestId }), + z.object({ action: z.literal("cancel"), runId }), +]); + +export type CheckoutToolOutput = + | { status: "not_configured"; hint: string } + | { status: "error"; reason: string; message: string } + | CheckoutSnapshot; + +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; +} + +export const WAIT_MS = 90_000; + +export default defineTool({ + description: + "Buy from a merchant through Crossmint Agent Checkouts with a hard spending cap. Crossmint runs the checkout in its own service, not in this conversation's browser. Actions: start (product URL, plain-language task, maxCost), then follow requiredAction. For a form, call answer with one value per field key. For a payment request, call crossmint_pay; the person approves the exact amount there. decline refuses a request; cancel stops the run. Returns status snapshots only. A succeeded result whose purchase.kind is 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(); + if (!isCrossmintConfigured()) { + return { + status: "not_configured", + hint: "Set CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID on the server. See docs/crossmint.md.", + }; + } + const sessionId = ctx.session.id; + const signal = ctx.abortSignal; + try { + switch (input.action) { + case "start": { + const { runId } = await createCheckout( + { + startUrl: input.startUrl, + task: input.task, + maxCost: input.maxCost, + ...(input.merchantGuidance ? { merchantGuidance: input.merchantGuidance } : {}), + ...(input.countryCode ? { countryCode: input.countryCode } : {}), + }, + { signal }, + ); + rememberCheckout(sessionId, { + runId, + maxCost: input.maxCost, + principalId: ctx.session.auth.current?.principalId ?? null, + }); + return await waitForCheckout(runId, { signal, timeoutMs: WAIT_MS }); + } + case "status": { + assertSessionCheckout(sessionId, input.runId); + return await waitForCheckout(input.runId, { signal, timeoutMs: WAIT_MS }); + } + case "answer": { + 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 waitForCheckout(input.runId, { + signal, + timeoutMs: WAIT_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..8b28a0f --- /dev/null +++ b/agent/tools/crossmint_pay.ts @@ -0,0 +1,123 @@ +import { defineTool, toolOutput } from "eve/tools"; +import { always } from "eve/tools/approval"; +import { z } from "zod"; + +import { + CrossmintSetupError, + getCheckout, + isCrossmintConfigured, + payWithOrderIntent, + waitForCheckout, +} from "../../server/crossmint/client"; +import { assertPaymentMatches, PaymentMismatchError } from "../../server/crossmint/payment"; +import { assertSessionCheckout } from "../../server/crossmint/runs"; +import { errorOutput, WAIT_MS, type CheckoutToolOutput } from "./crossmint_checkout"; + +const inputSchema = z.object({ + runId: z.string().min(1).max(200), + requestId: z.string().min(1).max(200).describe("The open payment request's id."), + amount: z + .string() + .regex(/^\d+(\.\d{1,2})?$/) + .describe("The exact total Crossmint is asking for, copied from the payment request."), + currency: z.string().length(3).toUpperCase(), + merchant: z + .string() + .min(1) + .max(255) + .describe("The merchant URL or host from the payment request."), +}); + +type Input = z.infer; + +type PayOutput = + | CheckoutToolOutput + | { status: "payment_not_configured"; runId: string; requestId: string; hint: string }; + +export default defineTool({ + description: + "Pay an open Crossmint checkout payment request with the operator's order intent. Copy amount, currency, and merchant exactly from the payment request. Eve stops and asks the person to approve this call; the server then checks those three values against the live request and the checkout's cap before paying, and refuses on any difference. Requires 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 ${input.merchant} through Crossmint`, + }, + approval: { + request: always(), + prompt: ({ input }) => + `Pay ${input.amount} ${input.currency} to ${input.merchant} with your Crossmint order intent?`, + response: ({ request, response }) => { + 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." }; + }, + }, + async execute(input, ctx): Promise { + ctx.abortSignal.throwIfAborted(); + if (!isCrossmintConfigured()) { + return { + status: "not_configured", + hint: "Set CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID on the server. See docs/crossmint.md.", + }; + } + const sessionId = ctx.session.id; + const signal = ctx.abortSignal; + 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.", + }; + } + try { + const record = assertSessionCheckout(sessionId, input.runId); + if (record.principalId !== null && record.principalId !== auth.principalId) { + return { + status: "error", + reason: "principal_mismatch", + message: "A different sender started this checkout.", + }; + } + const live = await getCheckout(input.runId, { signal }); + try { + assertPaymentMatches(input, live, record); + } catch (error) { + if (error instanceof PaymentMismatchError) { + return { status: "error", reason: error.reason, message: error.message }; + } + throw error; + } + try { + await payWithOrderIntent(input.runId, input.requestId, { signal }); + } catch (error) { + 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/docs/crossmint.md b/docs/crossmint.md new file mode 100644 index 0000000..98b4722 --- /dev/null +++ b/docs/crossmint.md @@ -0,0 +1,133 @@ +# Crossmint Agent Checkouts + +Bell's `crossmint_checkout` and `crossmint_pay` tools buy from a merchant through +[Crossmint Agent Checkouts](https://docs.crossmint.com/agents/checkouts/overview). One request +carries a product URL, a plain-language task, and a spending cap. Crossmint runs the checkout in +its own service and exposes it as a run with status snapshots. Payment comes from an order intent +the operator approved in Crossmint beforehand, funded by a Crossmint agent card, a card on file, or +an agent card from another provider such as Link. + +```text +Bell -> create run (URL, task, cap) -> Crossmint works through the merchant checkout + -> 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 does not use this conversation's Browserbase browser. Link, the browser runtime, and +the hooks are unchanged. With the Crossmint variables unset, both tools return `not_configured`. + +## Configure + +Server-only values in Bell's ignored `.env.local`: + +```dotenv +CROSSMINT_SERVER_API_KEY= +CROSSMINT_USER_ID= +# Optional until the first payment: the operator's approved order intent id. +CROSSMINT_ORDER_INTENT_ID= +# Optional. Saved buyer profile (name, email, shipping) so checkouts ask fewer questions. +CROSSMINT_BUYER_PROFILE_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 merchant. +CROSSMINT_ALLOWED_MERCHANTS=https://shop.example +``` + +Create the key in the [Crossmint console](https://www.crossmint.com/console) with the +`agent-checkouts.create`, `.read`, `.update`, and `.cancel` scopes. Agent Checkouts run in +production only; a staging key returns `unauthorized`. Client keys (`ck_`) are rejected at startup. + +`CROSSMINT_USER_ID` identifies the buyer to Crossmint. Bell serves one trusted operator, so a fixed +value is enough; every run, order intent, and receipt is scoped to it. + +`CROSSMINT_ORDER_INTENT_ID` is the budget the operator approved in Crossmint: a saved card plus an +amount, merchant scope, and expiry. The [cards quickstart](https://docs.crossmint.com/agents/cards-quickstart) +walks through saving a card and approving an order intent. Only the `pay` path on the server reads +this id. Without it, checkouts run up to the payment step and `crossmint_pay` returns +`payment_not_configured`. + +`CROSSMINT_MAX_COST` and `CROSSMINT_ALLOWED_MERCHANTS` are checked before a run is created, so a +refused request is never billed. They bound what a prompt can ask for; the order intent still bounds +what can be paid. + +Restart Bell after changing these values. No database, migration, or browser setting is involved. + +## Use + +With `pnpm dev` running, in a web conversation or a Linq chat: + +1. "Buy one sticker pack from https://shop.example/products/sticker-pack, standard delivery, max + 20 USD." Bell starts the run and waits up to 90 seconds for the next step. +2. When Crossmint asks a form question (size, email, delivery option), Bell asks you and answers + with the `answer` action. Fields marked `protected` (one-time codes, passwords, card data) cannot + be answered through the model; Bell declines or asks you to finish in Crossmint's hosted flow. +3. At the payment step Bell calls `crossmint_pay` with the amount, currency, and merchant from the + request. Eve pauses and shows you an approval: "Pay 12.49 USD to shop.example with your + Crossmint order intent?" Approving runs the tool; cancelling does not. Only the authenticated + sender who asked for the purchase can approve. +4. `succeeded` with `purchase.kind: receipt_captured` carries `receipt.total` and + `receipt.merchantOrderId`. That is the only result Bell reports as a placed order. + `confirmed_without_receipt` and `nothing_placed` are reported as what they are. + +`blocked` returns a code such as `merchant.payment_declined`, `policy.max_cost_exceeded`, or +`product.item_unavailable`; `failed` returns 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. + +Crossmint bills each run that starts, including runs that end `blocked`. 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 merchant the model put in the call. After approval the server fetches the live +payment request from Crossmint and compares it with those three values and with the cap the run was +started under. Any difference, an expired or replaced request, a `maximum` instead of an `exact` +amount, or a run this conversation did not start refuses the payment and returns 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: 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. + +## Transcript boundary + +Only a projection of each snapshot reaches the model: run id, status, revision, the open question +with its form fields or payment amount and merchant, and the result summary with receipt metadata. +Browser embed URLs, 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. + +Runs are registered per conversation in process memory, like the Link sandbox request set. 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 merchant's own records are outside Bell's control. Transcripts still contain +the merchant, items, totals, and form answers, so apply your host's retention policy. + +## When to use this instead of Bell's browser + +For merchants that support an agentic commerce protocol, Agent Checkouts is a pure API call with no +browser session anywhere. For other merchants Crossmint runs its own browser and per-merchant +behavior in its service, so fixes land without a change in Bell. Bell's own browser tools and +`link__checkout` remain the path when the purchase has to happen inside this conversation's +Browserbase session, for example after Baselayer-verified access or in a saved Context. + +## Verify + +`pnpm check` runs mock provider tests: request shapes and headers against the documented API, +sanitized errors, the merchant allowlist and spending ceiling, snapshot projection including +protected fields and payment interactions, the payment cross-check with one case per refusal +reason, polling with an answered request skipped, the timeout and cancellation paths, and +per-conversation run isolation. No test calls Crossmint. + +For a live smoke test, set the key and buyer id, pick a merchant test checkout or an item under a +few dollars, and run the four steps above. Watch the run in the Crossmint console and compare the +receipt with the merchant'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), +[pay for a checkout](https://docs.crossmint.com/agents/checkouts/payments), +[API reference](https://docs.crossmint.com/api-reference/agent-checkouts/create-agent-checkout). diff --git a/docs/repository.md b/docs/repository.md index f77d120..f75be39 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), [server client](../server/crossmint/client.ts), [payment cross-check](../server/crossmint/payment.ts) | [Agent checkouts](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/server/crossmint/client.ts b/server/crossmint/client.ts new file mode 100644 index 0000000..e2881a7 --- /dev/null +++ b/server/crossmint/client.ts @@ -0,0 +1,622 @@ +import { randomUUID } from "node:crypto"; + +/** + * Crossmint Agent Checkouts, server side. + * + * Crossmint runs the merchant checkout in its own service 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"; + } +} + +export type CrossmintRequestReason = + | "unauthorized" + | "not_found" + | "rate_limited" + | "transport" + | "invalid_response" + | "http_error"; + +export class CrossmintRequestError extends Error { + constructor( + readonly reason: CrossmintRequestReason, + readonly status?: number, + ) { + super( + reason === "unauthorized" + ? "Crossmint rejected the API key or its scopes." + : reason === "not_found" + ? "Crossmint has no checkout with that id for this buyer." + : reason === "rate_limited" + ? "Crossmint rate limited the request. Retry shortly." + : reason === "transport" + ? "Crossmint request failed. Check connectivity and retry." + : reason === "invalid_response" + ? "Crossmint returned an unexpected response." + : `Crossmint returned HTTP ${status}.`, + ); + 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"; + +const DECIMAL = /^\d+(\.\d{1,2})?$/; +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 apiKey = required("CROSSMINT_SERVER_API_KEY"); + if (!apiKey.startsWith("sk_")) throw invalid("CROSSMINT_SERVER_API_KEY"); + const userId = required("CROSSMINT_USER_ID"); + + const baseUrl = env.CROSSMINT_API_BASE_URL?.trim() || DEFAULT_BASE_URL; + let base: URL; + try { + base = new URL(baseUrl); + } catch { + throw invalid("CROSSMINT_API_BASE_URL"); + } + if (base.protocol !== "https:" || base.username || base.password || 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 || !currency || !DECIMAL.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) { + let url: URL; + try { + url = new URL(origin); + } catch { + throw invalid("CROSSMINT_ALLOWED_MERCHANTS"); + } + if (url.protocol !== "https:" || url.origin !== origin || url.username || url.password) { + 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 without floating point. 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(2, "0").slice(0, 2)); + }; + 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) { + let url: URL; + try { + url = new URL(startUrl); + } catch { + throw new CrossmintPolicyError("merchant_not_allowed", "The start URL is not a valid HTTPS URL."); + } + if ( + 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"; + +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"; + type: string; + choices?: string[]; +} + +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; +} + +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 { + signal.throwIfAborted(); + throw new CrossmintRequestError("transport"); + } + if (!response.ok) { + // Provider bodies can echo the request, the key prefix, or merchant data. Drop them. + if (response.status === 401 || response.status === 403) { + throw new CrossmintRequestError("unauthorized", response.status); + } + if (response.status === 404) throw new CrossmintRequestError("not_found", 404); + if (response.status === 429) throw new CrossmintRequestError("rate_limited", 429); + throw new CrossmintRequestError("http_error", 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); + } +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +function asString(value: unknown): string | undefined { + return typeof value === "string" ? value : undefined; +} + +function projectAmount(value: unknown): MaxCost | undefined { + if (!isRecord(value)) return undefined; + const amount = asString(value.amount); + const currency = asString(value.currency); + return amount && currency ? { amount, currency } : undefined; +} + +function projectInteraction(value: unknown): CheckoutInteraction { + if (!isRecord(value)) return { kind: "unsupported" }; + if (value.kind === "form" && Array.isArray(value.fields)) { + const fields: CheckoutFormField[] = []; + for (const field of value.fields) { + if (!isRecord(field)) continue; + const key = asString(field.key); + if (!key) continue; + const input = isRecord(field.input) ? field.input : {}; + const choices = Array.isArray(input.choices) + ? input.choices + .map((choice) => { + if (typeof choice === "string") return choice; + if (isRecord(choice)) return asString(choice.value) ?? asString(choice.label); + return undefined; + }) + .filter((choice): choice is string => Boolean(choice)) + : undefined; + fields.push({ + key, + label: asString(field.label) ?? key, + required: field.required === true, + handling: field.handling === "protected" ? "protected" : "standard", + type: asString(input.type) ?? "text", + ...(choices?.length ? { choices } : {}), + }); + } + return { kind: "form", fields }; + } + if (value.kind === "payment") { + const amount = isRecord(value.amount) ? value.amount : {}; + const merchant = isRecord(value.merchant) ? value.merchant : {}; + return { + kind: "payment", + method: asString(value.method) ?? "unknown", + amount: { + kind: amount.kind === "maximum" ? "maximum" : "exact", + value: asString(amount.value) ?? "", + currency: asString(amount.currency) ?? "", + }, + merchant: { + ...(asString(merchant.name) ? { name: asString(merchant.name) } : {}), + ...(asString(merchant.url) ? { url: asString(merchant.url) } : {}), + ...(asString(merchant.countryCode) ? { countryCode: asString(merchant.countryCode) } : {}), + }, + }; + } + return { kind: "unsupported" }; +} + +const STATUSES: ReadonlySet = new Set([ + "queued", + "running", + "awaiting_input", + "succeeded", + "failed", + "cancelled", + "blocked", +]); + +/** Project a raw snapshot to the fields the model may see. Anything unlisted is discarded. */ +export function projectCheckout(raw: unknown): CheckoutSnapshot { + if (!isRecord(raw)) throw new CrossmintRequestError("invalid_response"); + const runId = asString(raw.runId); + const status = asString(raw.status); + if (!runId || !status || !STATUSES.has(status)) { + throw new CrossmintRequestError("invalid_response"); + } + const revision = typeof raw.revision === "number" ? raw.revision : 0; + let requiredAction: CheckoutRequiredAction | null = null; + if (status === "awaiting_input" && isRecord(raw.requiredAction)) { + const action = raw.requiredAction; + const requestId = asString(action.requestId); + const req = isRecord(action.request) ? action.request : {}; + if (requestId) { + requiredAction = { + requestId, + question: asString(req.question) ?? "", + ...(asString(req.expiresAt) ? { expiresAt: asString(req.expiresAt) } : {}), + interaction: projectInteraction(req.interaction), + }; + } + } + let result: CheckoutSnapshot["result"] = null; + if (isRecord(raw.result)) { + const purchase = isRecord(raw.result.purchase) ? raw.result.purchase : undefined; + const receipt = purchase && isRecord(purchase.receipt) ? purchase.receipt : undefined; + const kind = purchase ? asString(purchase.kind) : undefined; + result = { + ...(asString(raw.result.outcome) ? { outcome: asString(raw.result.outcome) } : {}), + ...(asString(raw.result.summary) ? { summary: asString(raw.result.summary) } : {}), + ...(asString(raw.result.code) ? { code: asString(raw.result.code) } : {}), + ...(kind + ? { + purchase: { + kind, + ...(receipt + ? { + receipt: { + ...(projectAmount(receipt.total) ? { total: projectAmount(receipt.total) } : {}), + ...(asString(receipt.merchantOrderId) + ? { merchantOrderId: asString(receipt.merchantOrderId) } + : {}), + }, + } + : {}), + }, + } + : {}), + }; + } + return { + runId, + status: status as CheckoutStatus, + revision, + requiredAction, + result, + failureReason: status === "failed" ? (asString(raw.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 }, + ...(config.buyerProfileId ? { buyerProfileId: config.buyerProfileId } : {}), + ...(input.merchantGuidance ? { merchantGuidance: input.merchantGuidance } : {}), + ...(input.countryCode + ? { browser: { location: { type: "country", countryCode: input.countryCode } } } + : {}), + }; + const raw = await request("/agent-checkouts", { method: "POST", body }, { ...options, config }); + const runId = isRecord(raw) ? asString(raw.runId) : undefined; + if (!runId) throw new CrossmintRequestError("invalid_response"); + return { runId }; +} + +export async function getCheckout( + runId: string, + options: CrossmintClientOptions = {}, +): Promise { + const raw = await request( + `/agent-checkouts/${encodeURIComponent(runId)}`, + { method: "GET" }, + options, + ); + return projectCheckout(raw); +} + +export type FormAnswer = string | number | boolean | string[]; + +function message(parts: unknown[]) { + return { id: `bell_${randomUUID()}`, parts }; +} + +export async function answerForm( + runId: string, + requestId: string, + answers: Record, + options: CrossmintClientOptions = {}, +): Promise { + await request( + `/agent-checkouts/${encodeURIComponent(runId)}/messages`, + { + method: "POST", + body: message([ + { + type: "input_response", + 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 request( + `/agent-checkouts/${encodeURIComponent(runId)}/messages`, + { + method: "POST", + body: message([ + { + type: "input_response", + requestId, + action: "submit", + response: { kind: "payment", orderIntentId: config.orderIntentId }, + }, + ]), + }, + { ...options, config }, + ); +} + +export async function declineRequest( + runId: string, + requestId: string, + options: CrossmintClientOptions = {}, +): Promise { + await request( + `/agent-checkouts/${encodeURIComponent(runId)}/messages`, + { method: "POST", body: message([{ type: "input_response", requestId, action: "decline" }]) }, + options, + ); +} + +export async function cancelCheckout( + runId: string, + options: CrossmintClientOptions = {}, +): Promise { + await request(`/agent-checkouts/${encodeURIComponent(runId)}/cancel`, { method: "POST" }, options); +} + +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; +} + +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 timeoutMs = options.timeoutMs ?? 90_000; + const intervalMs = options.intervalMs ?? 2_000; + const deadline = Date.now() + timeoutMs; + let snapshot = await getCheckout(runId, options); + for (;;) { + const settled = + TERMINAL_STATUSES.has(snapshot.status) || + (snapshot.status === "awaiting_input" && + snapshot.requiredAction !== null && + snapshot.requiredAction.requestId !== options.skipRequestId); + if (settled || Date.now() >= deadline) return 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/payment.ts b/server/crossmint/payment.ts new file mode 100644 index 0000000..f8b3c2b --- /dev/null +++ b/server/crossmint/payment.ts @@ -0,0 +1,91 @@ +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; +} + +export class PaymentMismatchError extends Error { + constructor( + readonly reason: + | "no_payment_request" + | "request_changed" + | "amount_mismatch" + | "currency_mismatch" + | "merchant_mismatch" + | "cap_exceeded" + | "unsupported_amount", + message: string, + ) { + super(message); + this.name = "PaymentMismatchError"; + } +} + +function hostOf(value: string): string | undefined { + try { + return new URL(value.includes("://") ? value : `https://${value}`).hostname.toLowerCase(); + } catch { + return undefined; + } +} + +/** + * 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 action = live.requiredAction; + if (live.status !== "awaiting_input" || !action || action.interaction.kind !== "payment") { + throw new PaymentMismatchError( + "no_payment_request", + "Crossmint is not waiting for a payment on this checkout.", + ); + } + if (action.requestId !== approved.requestId) { + throw new PaymentMismatchError( + "request_changed", + "The payment request changed since approval. Show the person the new request.", + ); + } + const { amount, merchant } = action.interaction; + if (amount.kind !== "exact") { + throw new PaymentMismatchError( + "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 new PaymentMismatchError("currency_mismatch", "The approved currency differs from Crossmint's."); + } + if (compareAmounts(amount.value, approved.amount) !== 0) { + throw new PaymentMismatchError( + "amount_mismatch", + `Crossmint is asking for ${amount.value} ${amount.currency}, not the approved amount.`, + ); + } + const liveHost = merchant.url ? hostOf(merchant.url) : undefined; + const approvedHost = hostOf(approved.merchant); + if (!liveHost || !approvedHost || liveHost !== approvedHost) { + throw new PaymentMismatchError( + "merchant_mismatch", + "The approved merchant differs from the one Crossmint is checking out at.", + ); + } + if (record.maxCost.currency !== amount.currency || compareAmounts(amount.value, record.maxCost.amount) > 0) { + throw new PaymentMismatchError( + "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..485e824 --- /dev/null +++ b/server/crossmint/runs.ts @@ -0,0 +1,41 @@ +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, like the Link sandbox request set. 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; +} + +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.test.ts b/tests/crossmint.test.ts new file mode 100644 index 0000000..8944b21 --- /dev/null +++ b/tests/crossmint.test.ts @@ -0,0 +1,367 @@ +import { describe, expect, it, vi } from "vitest"; +import { + answerForm, + assertCheckoutPolicy, + cancelCheckout, + compareAmounts, + createCheckout, + crossmintConfig, + CrossmintPolicyError, + CrossmintRequestError, + CrossmintSetupError, + declineRequest, + getCheckout, + isCrossmintConfigured, + payWithOrderIntent, + projectCheckout, + 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"; + +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") => + snapshot({ + status: "awaiting_input", + requiredAction: { + requestId: "req_pay", + request: { + question: `Authorize a card payment of ${amount} ${currency}.`, + interaction: { + kind: "payment", + method: "card", + purpose: "checkout_payment", + amount: { kind: "exact", value: amount, currency }, + merchant: { name: "Example Shop", url, countryCode: "US" }, + }, + }, + }, + }); + +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_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("compares decimal amounts without floating point", () => { + 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); + }); + + 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"]) { + 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].response).toEqual({ 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]).toMatchObject({ 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(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 () => { 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 a form request and keeps 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: { type: "choice", choices: [{ value: "M", label: "Medium" }, "L"] } }, + { key: "otp", label: "Code", required: true, handling: "protected", input: { type: "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", type: "choice", choices: ["M", "L"] }, + { key: "otp", label: "Code", required: true, handling: "protected", type: "text" }, + ], + }, + }); + }); + + it("projects a payment request to 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"); + }); + + 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: "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); + }); +}); + +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()], + ["amount_mismatch", { ...approved, amount: "12.48" }, paymentRequest()], + ["currency_mismatch", { ...approved, currency: "EUR" }, 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); + }); + + it("refuses a maximum amount, which cannot be shown to the person as an exact total", () => { + const raw = paymentRequest(); + (raw.requiredAction as unknown as { request: { interaction: { amount: { kind: string } } } }).request.interaction.amount.kind = "maximum"; + expect(() => assertPaymentMatches(approved, live(raw), record)).toThrow(/maximum rather than an exact total/); + }); +}); + +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 }), + snapshot({ status: "awaiting_input", revision: 2, requiredAction: { requestId: "answered", request: { question: "old", interaction: { kind: "form", fields: [] } } } }), + snapshot({ status: "awaiting_input", revision: 3, requiredAction: { requestId: "req_new", request: { question: "new", interaction: { kind: "form", fields: [] } } } }), + ]; + 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"); + }); +}); From 6a21f8309b6db0cd4e528d65d610478d839eaf4e Mon Sep 17 00:00:00 2001 From: Alejandro Dopico Date: Wed, 28 Oct 2026 16:22:31 -0500 Subject: [PATCH 2/4] Add Crossmint Agent Checkouts as an optional way to buy One tool starts a checkout at any store with a product URL, a sentence and a spending cap, then answers the forms. A second tool pays after the person approves the exact total in Eve, and the server checks that total, the currency, the merchant and the cap against Crossmint's live request before paying. The card number never reaches Bell or the model. Nothing changes unless the Crossmint variables are set. --- .env.example | 4 +- README.md | 2 +- agent/instructions.md | 17 +- agent/lib/crossmint.ts | 35 +++ agent/tools/crossmint_checkout.ts | 135 ++------- agent/tools/crossmint_pay.ts | 94 ++---- docs/crossmint.md | 183 +++++++----- docs/repository.md | 2 +- scripts/demo-crossmint.mjs | 75 +++++ server/crossmint/client.ts | 481 ++++++++++-------------------- server/crossmint/payment.ts | 60 ++-- server/crossmint/runs.ts | 4 +- tests/crossmint.test.ts | 145 +++++++-- 13 files changed, 571 insertions(+), 666 deletions(-) create mode 100644 agent/lib/crossmint.ts create mode 100644 scripts/demo-crossmint.mjs diff --git a/.env.example b/.env.example index fcdc4a0..3c884db 100644 --- a/.env.example +++ b/.env.example @@ -67,8 +67,8 @@ LINK_TOKEN_ENCRYPTION_KEY= # Exact trusted checkout/frame origins per approved merchant (JSON object). LINK_CHECKOUT_ORIGINS={} -# Optional Crossmint Agent Checkouts. Production server key (sk_) with agent-checkouts.* scopes. -# See docs/crossmint.md. Leave unset to keep the tools disabled. +# Optional Crossmint Agent Checkouts. Buy at any store with the person's own card. +# Production server key (sk_) with agent-checkouts.* scopes. See docs/crossmint.md. Leave unset to keep the tools disabled. CROSSMINT_SERVER_API_KEY= CROSSMINT_USER_ID= # The operator's approved order intent id. Required only to pay; never shown to the model. diff --git a/README.md b/README.md index ab9c12b..3d03caf 100644 --- a/README.md +++ b/README.md @@ -40,7 +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 | Checkout at any merchant under a spending cap, paid after the person approves the exact total | [Agent checkouts](docs/crossmint.md) | +| Crossmint | Buy at any store with the person's own card, worldwide, under a spending cap the person approves | [Agent checkouts](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 b27068f..dd99a2e 100644 --- a/agent/instructions.md +++ b/agent/instructions.md @@ -40,11 +40,12 @@ Do not claim a successful mint or merchant access unless the tool result confirm 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. Start with the product URL, the -request, and the user's spending cap. Answer form questions from what the user said; never fill -protected fields. At a payment request, call crossmint_pay with the amount, currency, and merchant -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. +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. 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, and merchant 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. diff --git a/agent/lib/crossmint.ts b/agent/lib/crossmint.ts new file mode 100644 index 0000000..87cb67d --- /dev/null +++ b/agent/lib/crossmint.ts @@ -0,0 +1,35 @@ +import { z } from "zod"; +import { + AMOUNT, + CrossmintPolicyError, + CrossmintRequestError, + CrossmintSetupError, + isCrossmintConfigured, + type CheckoutSnapshot, +} from "../../server/crossmint/client"; + +/** How long one tool call waits for Crossmint before returning the latest snapshot. */ +export const WAIT_MS = 90_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." }; +} + +/** 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_checkout.ts b/agent/tools/crossmint_checkout.ts index fd94ca5..a024df4 100644 --- a/agent/tools/crossmint_checkout.ts +++ b/agent/tools/crossmint_checkout.ts @@ -1,53 +1,17 @@ import { defineTool, toolOutput } from "eve/tools"; import { z } from "zod"; - -import { - answerForm, - cancelCheckout, - createCheckout, - CrossmintPolicyError, - CrossmintRequestError, - CrossmintSetupError, - declineRequest, - getCheckout, - isCrossmintConfigured, - waitForCheckout, - type CheckoutSnapshot, -} from "../../server/crossmint/client"; +import { amount, currency, errorOutput, notConfigured, requestId, runId, WAIT_MS, type CheckoutToolOutput } from "../lib/crossmint"; +import { answerForm, cancelCheckout, createCheckout, declineRequest, getCheckout, waitForCheckout } from "../../server/crossmint/client"; import { assertSessionCheckout, rememberCheckout } from "../../server/crossmint/runs"; -const maxCost = z.object({ - amount: z - .string() - .regex(/^\d+(\.\d{1,2})?$/, "Decimal string such as 20.00") - .describe("Spending cap including shipping and tax, as a decimal string."), - currency: z.string().length(3).toUpperCase().describe("ISO 4217 code, such as USD or EUR."), -}); - -const runId = z.string().min(1).max(200); -const requestId = z.string().min(1).max(200); - 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, - merchantGuidance: z - .string() - .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."), + 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({ @@ -56,120 +20,63 @@ const inputSchema = z.discriminatedUnion("action", [ 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. Protected fields cannot be answered here."), + .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 type CheckoutToolOutput = - | { status: "not_configured"; hint: string } - | { status: "error"; reason: string; message: string } - | CheckoutSnapshot; - -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; -} - -export const WAIT_MS = 90_000; - export default defineTool({ description: - "Buy from a merchant through Crossmint Agent Checkouts with a hard spending cap. Crossmint runs the checkout in its own service, not in this conversation's browser. Actions: start (product URL, plain-language task, maxCost), then follow requiredAction. For a form, call answer with one value per field key. For a payment request, call crossmint_pay; the person approves the exact amount there. decline refuses a request; cancel stops the run. Returns status snapshots only. A succeeded result whose purchase.kind is receipt_captured is the only proof of a placed order. Never start a second checkout for the same request while one is unresolved.", + "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 and waits up to ninety seconds for the next step. 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}`, + 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(); - if (!isCrossmintConfigured()) { - return { - status: "not_configured", - hint: "Set CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID on the server. See docs/crossmint.md.", - }; - } + 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( - { - startUrl: input.startUrl, - task: input.task, - maxCost: input.maxCost, - ...(input.merchantGuidance ? { merchantGuidance: input.merchantGuidance } : {}), - ...(input.countryCode ? { countryCode: input.countryCode } : {}), - }, - { signal }, - ); - rememberCheckout(sessionId, { - runId, - maxCost: input.maxCost, - principalId: ctx.session.auth.current?.principalId ?? null, - }); + const { runId } = await createCheckout(input, { signal }); + rememberCheckout(sessionId, { runId, maxCost: input.maxCost, principalId: ctx.session.auth.current?.principalId ?? null }); return await waitForCheckout(runId, { signal, timeoutMs: WAIT_MS }); } - case "status": { + case "status": assertSessionCheckout(sessionId, input.runId); return await waitForCheckout(input.runId, { signal, timeoutMs: WAIT_MS }); - } case "answer": { 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.", - }; + 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), - ); + 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.", + 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 waitForCheckout(input.runId, { - signal, - timeoutMs: WAIT_MS, - skipRequestId: input.requestId, - }); + return await waitForCheckout(input.runId, { signal, timeoutMs: WAIT_MS, skipRequestId: input.requestId }); } - case "decline": { + 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": { + 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); diff --git a/agent/tools/crossmint_pay.ts b/agent/tools/crossmint_pay.ts index 8b28a0f..6c2c2c1 100644 --- a/agent/tools/crossmint_pay.ts +++ b/agent/tools/crossmint_pay.ts @@ -1,103 +1,59 @@ import { defineTool, toolOutput } from "eve/tools"; import { always } from "eve/tools/approval"; import { z } from "zod"; - -import { - CrossmintSetupError, - getCheckout, - isCrossmintConfigured, - payWithOrderIntent, - waitForCheckout, -} from "../../server/crossmint/client"; +import { amount, currency, errorOutput, notConfigured, requestId, 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"; -import { errorOutput, WAIT_MS, type CheckoutToolOutput } from "./crossmint_checkout"; const inputSchema = z.object({ - runId: z.string().min(1).max(200), - requestId: z.string().min(1).max(200).describe("The open payment request's id."), - amount: z - .string() - .regex(/^\d+(\.\d{1,2})?$/) - .describe("The exact total Crossmint is asking for, copied from the payment request."), - currency: z.string().length(3).toUpperCase(), - merchant: z - .string() - .min(1) - .max(255) - .describe("The merchant URL or host from the payment request."), + 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."), }); type Input = z.infer; -type PayOutput = - | CheckoutToolOutput - | { status: "payment_not_configured"; runId: string; requestId: string; hint: string }; +type PayOutput = CheckoutToolOutput | { status: "payment_not_configured"; runId: string; requestId: string; hint: string }; export default defineTool({ description: - "Pay an open Crossmint checkout payment request with the operator's order intent. Copy amount, currency, and merchant exactly from the payment request. Eve stops and asks the person to approve this call; the server then checks those three values against the live request and the checkout's cap before paying, and refuses on any difference. Requires an authenticated sender. Call once per payment request. Use crossmint_checkout decline if the person says no.", + "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. 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 ${input.merchant} through Crossmint`, + start: (input: Readonly) => `Paying ${input.amount} ${input.currency} at ${input.merchant} through Crossmint`, }, approval: { request: always(), - prompt: ({ input }) => - `Pay ${input.amount} ${input.currency} to ${input.merchant} with your Crossmint order intent?`, + prompt: ({ input }) => `Pay ${input.amount} ${input.currency} to ${input.merchant} with your Crossmint order intent?`, response: ({ request, response }) => { 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." }; + 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." }; }, }, async execute(input, ctx): Promise { ctx.abortSignal.throwIfAborted(); - if (!isCrossmintConfigured()) { - return { - status: "not_configured", - hint: "Set CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID on the server. See docs/crossmint.md.", - }; - } - const sessionId = ctx.session.id; - const signal = ctx.abortSignal; + 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.", - }; + 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(sessionId, input.runId); + 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.", - }; - } - const live = await getCheckout(input.runId, { signal }); - try { - assertPaymentMatches(input, live, record); - } catch (error) { - if (error instanceof PaymentMismatchError) { - return { status: "error", reason: error.reason, message: error.message }; - } - throw error; + 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", @@ -108,11 +64,7 @@ export default defineTool({ } throw error; } - return await waitForCheckout(input.runId, { - signal, - timeoutMs: WAIT_MS, - skipRequestId: input.requestId, - }); + return await waitForCheckout(input.runId, { signal, timeoutMs: WAIT_MS, skipRequestId: input.requestId }); } catch (error) { return errorOutput(error); } diff --git a/docs/crossmint.md b/docs/crossmint.md index 98b4722..d3ef6f5 100644 --- a/docs/crossmint.md +++ b/docs/crossmint.md @@ -1,133 +1,164 @@ # Crossmint Agent Checkouts -Bell's `crossmint_checkout` and `crossmint_pay` tools buy from a merchant through -[Crossmint Agent Checkouts](https://docs.crossmint.com/agents/checkouts/overview). One request -carries a product URL, a plain-language task, and a spending cap. Crossmint runs the checkout in -its own service and exposes it as a run with status snapshots. Payment comes from an order intent -the operator approved in Crossmint beforehand, funded by a Crossmint agent card, a card on file, or -an agent card from another provider such as Link. +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 merchant checkout +Bell -> create run (URL, task, cap) -> Crossmint works through the store's checkout -> 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 does not use this conversation's Browserbase browser. Link, the browser runtime, and -the hooks are unchanged. With the Crossmint variables unset, both tools return `not_configured`. +The checkout runs in Crossmint's service, not in this conversation's browser. Nothing in the Link +integration, the browser runtime, or the hooks changes. With the Crossmint variables unset, both +tools answer `not_configured`. ## Configure -Server-only values in Bell's ignored `.env.local`: +Set these server-only values in Bell's ignored `.env.local`: ```dotenv CROSSMINT_SERVER_API_KEY= CROSSMINT_USER_ID= -# Optional until the first payment: the operator's approved order intent id. +# Needed only to pay. The operator's approved order intent id. CROSSMINT_ORDER_INTENT_ID= # Optional. Saved buyer profile (name, email, shipping) so checkouts ask fewer questions. CROSSMINT_BUYER_PROFILE_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 merchant. +# Optional. Exact HTTPS origins a checkout may start from. Empty allows any store. CROSSMINT_ALLOWED_MERCHANTS=https://shop.example ``` Create the key in the [Crossmint console](https://www.crossmint.com/console) with the -`agent-checkouts.create`, `.read`, `.update`, and `.cancel` scopes. Agent Checkouts run in -production only; a staging key returns `unauthorized`. Client keys (`ck_`) are rejected at startup. +`agent-checkouts.create`, `agent-checkouts.read`, `agent-checkouts.update`, and +`agent-checkouts.cancel` scopes. 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, order intent, and receipt is scoped to it. +value is enough. Every run, order intent, and receipt is scoped to it. -`CROSSMINT_ORDER_INTENT_ID` is the budget the operator approved in Crossmint: a saved card plus an -amount, merchant scope, and expiry. The [cards quickstart](https://docs.crossmint.com/agents/cards-quickstart) -walks through saving a card and approving an order intent. Only the `pay` path on the server reads -this id. Without it, checkouts run up to the payment step and `crossmint_pay` returns -`payment_not_configured`. +`CROSSMINT_ORDER_INTENT_ID` is the budget the person approved in Crossmint beforehand. It names a +saved card, an amount, a merchant scope, and an expiry. The card can be a Crossmint agent card, a card +on file, or an agent card from another provider. The +[cards quickstart](https://docs.crossmint.com/agents/cards-quickstart) walks through saving a card +and approving an order intent. Only the pay path on the server reads this id. Without it, checkouts +run up to the payment step and `crossmint_pay` answers `payment_not_configured`. -`CROSSMINT_MAX_COST` and `CROSSMINT_ALLOWED_MERCHANTS` are checked before a run is created, so a -refused request is never billed. They bound what a prompt can ask for; the order intent still bounds -what can be paid. +`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, migration, or browser setting is involved. +## Try it in five minutes + +This run needs only `CROSSMINT_SERVER_API_KEY` and `CROSSMINT_USER_ID`. 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 waits up to ninety seconds for the next step. +3. Answer the questions Bell relays, such as a size or an email. With a buyer profile configured + most of them do not come up. +4. At the payment step Bell calls `crossmint_pay`. Eve pauses and shows "Pay 12.49 USD to + shop.example with your Crossmint order intent?". Approve it. The server fetches the live request, + checks it, finds no order intent, 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, 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: +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`. -1. "Buy one sticker pack from https://shop.example/products/sticker-pack, standard delivery, max - 20 USD." Bell starts the run and waits up to 90 seconds for the next step. -2. When Crossmint asks a form question (size, email, delivery option), Bell asks you and answers - with the `answer` action. Fields marked `protected` (one-time codes, passwords, card data) cannot - be answered through the model; Bell declines or asks you to finish in Crossmint's hosted flow. -3. At the payment step Bell calls `crossmint_pay` with the amount, currency, and merchant from the - request. Eve pauses and shows you an approval: "Pay 12.49 USD to shop.example with your - Crossmint order intent?" Approving runs the tool; cancelling does not. Only the authenticated - sender who asked for the purchase can approve. -4. `succeeded` with `purchase.kind: receipt_captured` carries `receipt.total` and - `receipt.merchantOrderId`. That is the only result Bell reports as a placed order. - `confirmed_without_receipt` and `nothing_placed` are reported as what they are. +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. -`blocked` returns a code such as `merchant.payment_declined`, `policy.max_cost_exceeded`, or -`product.item_unavailable`; `failed` returns 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. +At the payment step Bell calls `crossmint_pay` with the amount, currency, and merchant 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. -Crossmint bills each run that starts, including runs that end `blocked`. Keep the cap tight and do -not start a second run for the same request while one is unresolved. +`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 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 merchant the model put in the call. After approval the server fetches the live -payment request from Crossmint and compares it with those three values and with the cap the run was -started under. Any difference, an expired or replaced request, a `maximum` instead of an `exact` -amount, or a run this conversation did not start refuses the payment and returns 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: 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 +currency, and merchant the model put in the call. After approval the server fetches the live payment +request from Crossmint and compares it with those three values 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. ## Transcript boundary -Only a projection of each snapshot reaches the model: run id, status, revision, the open question -with its form fields or payment amount and merchant, and the result summary with receipt metadata. -Browser embed URLs, 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. +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, and the result summary with receipt +metadata. 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. -Runs are registered per conversation in process memory, like the Link sandbox request set. After a -restart or worker change an unfinished run cannot be resumed from chat; reconcile it in the -Crossmint console before starting another. +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 merchant's own records are outside Bell's control. Transcripts still contain -the merchant, items, totals, and form answers, so apply your host's retention policy. +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. -## When to use this instead of Bell's browser +## Verify -For merchants that support an agentic commerce protocol, Agent Checkouts is a pure API call with no -browser session anywhere. For other merchants Crossmint runs its own browser and per-merchant -behavior in its service, so fixes land without a change in Bell. Bell's own browser tools and -`link__checkout` remain the path when the purchase has to happen inside this conversation's -Browserbase session, for example after Baselayer-verified access or in a saved Context. +`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, cover polling with an answered request skipped, the timeout and cancellation paths, +per-conversation run isolation, and both tools up to `payment_not_configured`. No test calls +Crossmint. -## Verify +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 +``` -`pnpm check` runs mock provider tests: request shapes and headers against the documented API, -sanitized errors, the merchant allowlist and spending ceiling, snapshot projection including -protected fields and payment interactions, the payment cross-check with one case per refusal -reason, polling with an answered request skipped, the timeout and cancellation paths, and -per-conversation run isolation. No test calls Crossmint. +The command loads `.env`, then `.env.local` when present. It starts the checkout with the key and +buyer id, prints the run id and each status change, 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 a live smoke test, set the key and buyer id, pick a merchant test checkout or an item under a -few dollars, and run the four steps above. Watch the run in the Crossmint console and compare the -receipt with the merchant's confirmation before trusting the flow for anything larger. +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), [pay for a checkout](https://docs.crossmint.com/agents/checkouts/payments), -[API reference](https://docs.crossmint.com/api-reference/agent-checkouts/create-agent-checkout). +[statuses and codes](https://docs.crossmint.com/agents/checkouts/statuses), +[API reference](https://docs.crossmint.com/api-reference/agent-checkouts). diff --git a/docs/repository.md b/docs/repository.md index f75be39..47eb6ce 100644 --- a/docs/repository.md +++ b/docs/repository.md @@ -33,7 +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), [server client](../server/crossmint/client.ts), [payment cross-check](../server/crossmint/payment.ts) | [Agent checkouts](crossmint.md) | +| Crossmint | [Checkout tool](../agent/tools/crossmint_checkout.ts), [approved payment tool](../agent/tools/crossmint_pay.ts), [shared tool helpers](../agent/lib/crossmint.ts), [server client](../server/crossmint/client.ts), [payment cross-check](../server/crossmint/payment.ts) | [Agent checkouts](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/scripts/demo-crossmint.mjs b/scripts/demo-crossmint.mjs new file mode 100644 index 0000000..818bdc2 --- /dev/null +++ b/scripts/demo-crossmint.mjs @@ -0,0 +1,75 @@ +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)`); + +const deadline = Date.now() + 10 * 60_000; +let last = ""; +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 === "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/crossmint/client.ts b/server/crossmint/client.ts index e2881a7..fdb84c4 100644 --- a/server/crossmint/client.ts +++ b/server/crossmint/client.ts @@ -3,9 +3,9 @@ import { randomUUID } from "node:crypto"; /** * Crossmint Agent Checkouts, server side. * - * Crossmint runs the merchant checkout in its own service 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. + * 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 */ @@ -19,32 +19,23 @@ export class CrossmintSetupError extends Error { } } -export type CrossmintRequestReason = - | "unauthorized" - | "not_found" - | "rate_limited" - | "transport" - | "invalid_response" - | "http_error"; +/** 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 === "unauthorized" - ? "Crossmint rejected the API key or its scopes." - : reason === "not_found" - ? "Crossmint has no checkout with that id for this buyer." - : reason === "rate_limited" - ? "Crossmint rate limited the request. Retry shortly." - : reason === "transport" - ? "Crossmint request failed. Check connectivity and retry." - : reason === "invalid_response" - ? "Crossmint returned an unexpected response." - : `Crossmint returned HTTP ${status}.`, - ); + super(reason === "http_error" ? `Crossmint returned HTTP ${status}.` : REQUEST_MESSAGES[reason]); this.name = "CrossmintRequestError"; } } @@ -81,64 +72,44 @@ export interface CrossmintConfig { export const DEFAULT_BASE_URL = "https://www.crossmint.com/api/unstable"; -const DECIMAL = /^\d+(\.\d{1,2})?$/; -const CURRENCY = /^[A-Z]{3}$/; +/** 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 { +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 { +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 baseUrl = env.CROSSMINT_API_BASE_URL?.trim() || DEFAULT_BASE_URL; - let base: URL; - try { - base = new URL(baseUrl); - } catch { - throw invalid("CROSSMINT_API_BASE_URL"); - } - if (base.protocol !== "https:" || base.username || base.password || base.search || base.hash) { - throw invalid("CROSSMINT_API_BASE_URL"); - } + 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 || !currency || !DECIMAL.test(amount) || !CURRENCY.test(currency)) { - throw invalid("CROSSMINT_MAX_COST"); - } + 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) ?? []; + const allowedMerchants = env.CROSSMINT_ALLOWED_MERCHANTS?.split(",").map((value) => value.trim()).filter(Boolean) ?? []; for (const origin of allowedMerchants) { - let url: URL; - try { - url = new URL(origin); - } catch { - throw invalid("CROSSMINT_ALLOWED_MERCHANTS"); - } - if (url.protocol !== "https:" || url.origin !== origin || url.username || url.password) { - throw invalid("CROSSMINT_ALLOWED_MERCHANTS"); - } + if (httpsUrl(origin, "CROSSMINT_ALLOWED_MERCHANTS").origin !== origin) throw invalid("CROSSMINT_ALLOWED_MERCHANTS"); } return { @@ -152,11 +123,11 @@ export function crossmintConfig( }; } -/** Compare two decimal strings without floating point. Returns -1, 0, or 1. */ +/** 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(2, "0").slice(0, 2)); + return BigInt(whole + fraction.padEnd(6, "0").slice(0, 6)); }; const left = scale(a); const right = scale(b); @@ -164,42 +135,19 @@ export function compareAmounts(a: string, b: string): number { } /** Enforce the operator's merchant allowlist and spending ceiling before anything is created. */ -export function assertCheckoutPolicy( - startUrl: string, - maxCost: MaxCost, - config: CrossmintConfig, -): void { +export function assertCheckoutPolicy(startUrl: string, maxCost: MaxCost, config: CrossmintConfig): void { if (config.allowedMerchants.length) { - let url: URL; - try { - url = new URL(startUrl); - } catch { - throw new CrossmintPolicyError("merchant_not_allowed", "The start URL is not a valid HTTPS URL."); - } - if ( - 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.", - ); + 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.`, - ); + 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}.`, - ); + throw new CrossmintPolicyError("cap_exceeded", `The spending cap exceeds the operator ceiling of ${config.maxCost.amount} ${config.maxCost.currency}.`); } } } @@ -212,21 +160,11 @@ export interface CreateCheckoutInput { countryCode?: string; } -export type CheckoutStatus = - | "queued" - | "running" - | "awaiting_input" - | "succeeded" - | "failed" - | "cancelled" - | "blocked"; - -export const TERMINAL_STATUSES: ReadonlySet = new Set([ - "succeeded", - "failed", - "cancelled", - "blocked", -]); +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 { @@ -234,8 +172,11 @@ export interface CheckoutFormField { label: string; required: boolean; handling: "standard" | "protected"; - type: string; - choices?: string[]; + /** 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 { @@ -272,10 +213,7 @@ export interface CheckoutSnapshot { outcome?: string; summary?: string; code?: string; - purchase?: { - kind: string; - receipt?: { total?: MaxCost; merchantOrderId?: string }; - }; + purchase?: { kind: string; receipt?: { total?: MaxCost; merchantOrderId?: string } }; } | null; failureReason: string | null; } @@ -288,11 +226,7 @@ export interface CrossmintClientOptions { const REQUEST_TIMEOUT_MS = 20_000; -async function request( - path: string, - init: { method: "GET" | "POST"; body?: unknown }, - options: CrossmintClientOptions, -): Promise { +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; @@ -311,17 +245,16 @@ async function request( signal, }); } catch { - signal.throwIfAborted(); + options.signal?.throwIfAborted(); throw new CrossmintRequestError("transport"); } if (!response.ok) { - // Provider bodies can echo the request, the key prefix, or merchant data. Drop them. - if (response.status === 401 || response.status === 403) { - throw new CrossmintRequestError("unauthorized", response.status); - } - if (response.status === 404) throw new CrossmintRequestError("not_found", 404); - if (response.status === 429) throw new CrossmintRequestError("rate_limited", 429); - throw new CrossmintRequestError("http_error", response.status); + 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; @@ -332,247 +265,161 @@ async function request( } } -function isRecord(value: unknown): value is Record { - return typeof value === "object" && value !== null && !Array.isArray(value); -} - -function asString(value: unknown): string | undefined { - return typeof value === "string" ? value : undefined; -} - -function projectAmount(value: unknown): MaxCost | undefined { - if (!isRecord(value)) return undefined; - const amount = asString(value.amount); - const currency = asString(value.currency); - return amount && currency ? { amount, currency } : undefined; +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(value: unknown): CheckoutInteraction { - if (!isRecord(value)) return { kind: "unsupported" }; +function projectInteraction(raw: unknown): CheckoutInteraction { + const value = record(raw); if (value.kind === "form" && Array.isArray(value.fields)) { - const fields: CheckoutFormField[] = []; - for (const field of value.fields) { - if (!isRecord(field)) continue; - const key = asString(field.key); - if (!key) continue; - const input = isRecord(field.input) ? field.input : {}; - const choices = Array.isArray(input.choices) - ? input.choices - .map((choice) => { - if (typeof choice === "string") return choice; - if (isRecord(choice)) return asString(choice.value) ?? asString(choice.label); - return undefined; - }) - .filter((choice): choice is string => Boolean(choice)) - : undefined; - fields.push({ - key, - label: asString(field.label) ?? key, - required: field.required === true, - handling: field.handling === "protected" ? "protected" : "standard", - type: asString(input.type) ?? "text", - ...(choices?.length ? { choices } : {}), - }); - } - return { kind: "form", fields }; + return { kind: "form", fields: value.fields.flatMap((field) => projectField(field) ?? []) }; } if (value.kind === "payment") { - const amount = isRecord(value.amount) ? value.amount : {}; - const merchant = isRecord(value.merchant) ? value.merchant : {}; + const amount = record(value.amount); + const merchant = record(value.merchant); return { kind: "payment", - method: asString(value.method) ?? "unknown", - amount: { - kind: amount.kind === "maximum" ? "maximum" : "exact", - value: asString(amount.value) ?? "", - currency: asString(amount.currency) ?? "", - }, - merchant: { - ...(asString(merchant.name) ? { name: asString(merchant.name) } : {}), - ...(asString(merchant.url) ? { url: asString(merchant.url) } : {}), - ...(asString(merchant.countryCode) ? { countryCode: asString(merchant.countryCode) } : {}), - }, + 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" }; } -const STATUSES: ReadonlySet = new Set([ - "queued", - "running", - "awaiting_input", - "succeeded", - "failed", - "cancelled", - "blocked", -]); - /** Project a raw snapshot to the fields the model may see. Anything unlisted is discarded. */ export function projectCheckout(raw: unknown): CheckoutSnapshot { - if (!isRecord(raw)) throw new CrossmintRequestError("invalid_response"); - const runId = asString(raw.runId); - const status = asString(raw.status); - if (!runId || !status || !STATUSES.has(status)) { - throw new CrossmintRequestError("invalid_response"); - } - const revision = typeof raw.revision === "number" ? raw.revision : 0; + 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; - if (status === "awaiting_input" && isRecord(raw.requiredAction)) { - const action = raw.requiredAction; - const requestId = asString(action.requestId); - const req = isRecord(action.request) ? action.request : {}; - if (requestId) { - requiredAction = { - requestId, - question: asString(req.question) ?? "", - ...(asString(req.expiresAt) ? { expiresAt: asString(req.expiresAt) } : {}), - interaction: projectInteraction(req.interaction), - }; - } + 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 (isRecord(raw.result)) { - const purchase = isRecord(raw.result.purchase) ? raw.result.purchase : undefined; - const receipt = purchase && isRecord(purchase.receipt) ? purchase.receipt : undefined; - const kind = purchase ? asString(purchase.kind) : undefined; - result = { - ...(asString(raw.result.outcome) ? { outcome: asString(raw.result.outcome) } : {}), - ...(asString(raw.result.summary) ? { summary: asString(raw.result.summary) } : {}), - ...(asString(raw.result.code) ? { code: asString(raw.result.code) } : {}), - ...(kind + 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 ? { - purchase: { - kind, - ...(receipt - ? { - receipt: { - ...(projectAmount(receipt.total) ? { total: projectAmount(receipt.total) } : {}), - ...(asString(receipt.merchantOrderId) - ? { merchantOrderId: asString(receipt.merchantOrderId) } - : {}), - }, - } - : {}), - }, + 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, + revision: typeof run.revision === "number" ? run.revision : 0, requiredAction, result, - failureReason: status === "failed" ? (asString(raw.reason) ?? "unknown") : null, + failureReason: status === "failed" ? (string(run.reason) ?? "unknown") : null, }; } -export async function createCheckout( - input: CreateCheckoutInput, - options: CrossmintClientOptions = {}, -): Promise<{ runId: string }> { +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 }, - ...(config.buyerProfileId ? { buyerProfileId: config.buyerProfileId } : {}), - ...(input.merchantGuidance ? { merchantGuidance: input.merchantGuidance } : {}), - ...(input.countryCode - ? { browser: { location: { type: "country", countryCode: input.countryCode } } } - : {}), + ...present({ + buyerProfileId: config.buyerProfileId, + merchantGuidance: input.merchantGuidance, + browser: input.countryCode ? { location: { type: "country", countryCode: input.countryCode } } : undefined, + }), }; - const raw = await request("/agent-checkouts", { method: "POST", body }, { ...options, config }); - const runId = isRecord(raw) ? asString(raw.runId) : 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 { - const raw = await request( - `/agent-checkouts/${encodeURIComponent(runId)}`, - { method: "GET" }, - options, - ); - return projectCheckout(raw); +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[]; -function message(parts: unknown[]) { - return { id: `bell_${randomUUID()}`, parts }; -} - -export async function answerForm( - runId: string, - requestId: string, - answers: Record, - options: CrossmintClientOptions = {}, -): Promise { +/** 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: message([ - { - type: "input_response", - requestId, - action: "submit", - response: { kind: "form", answers }, - }, - ]), - }, + { 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 { +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 request( - `/agent-checkouts/${encodeURIComponent(runId)}/messages`, - { - method: "POST", - body: message([ - { - type: "input_response", - requestId, - action: "submit", - response: { kind: "payment", orderIntentId: config.orderIntentId }, - }, - ]), - }, - { ...options, config }, - ); + 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 async function declineRequest( - runId: string, - requestId: string, - options: CrossmintClientOptions = {}, -): Promise { - await request( - `/agent-checkouts/${encodeURIComponent(runId)}/messages`, - { method: "POST", body: message([{ type: "input_response", requestId, action: "decline" }]) }, - options, - ); +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 { +export async function cancelCheckout(runId: string, options: CrossmintClientOptions = {}): Promise { await request(`/agent-checkouts/${encodeURIComponent(runId)}/cancel`, { method: "POST" }, options); } @@ -599,20 +446,14 @@ function sleep(ms: number, signal?: AbortSignal): Promise { } /** 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 timeoutMs = options.timeoutMs ?? 90_000; +export async function waitForCheckout(runId: string, options: WaitOptions = {}): Promise { const intervalMs = options.intervalMs ?? 2_000; - const deadline = Date.now() + timeoutMs; + const deadline = Date.now() + (options.timeoutMs ?? 90_000); let snapshot = await getCheckout(runId, options); for (;;) { const settled = TERMINAL_STATUSES.has(snapshot.status) || - (snapshot.status === "awaiting_input" && - snapshot.requiredAction !== null && - snapshot.requiredAction.requestId !== options.skipRequestId); + (snapshot.status === "awaiting_input" && snapshot.requiredAction !== null && snapshot.requiredAction.requestId !== options.skipRequestId); if (settled || Date.now() >= deadline) return snapshot; options.signal?.throwIfAborted(); await sleep(Math.min(intervalMs, Math.max(0, deadline - Date.now())), options.signal); diff --git a/server/crossmint/payment.ts b/server/crossmint/payment.ts index f8b3c2b..bcff283 100644 --- a/server/crossmint/payment.ts +++ b/server/crossmint/payment.ts @@ -14,11 +14,12 @@ export class PaymentMismatchError extends Error { readonly reason: | "no_payment_request" | "request_changed" - | "amount_mismatch" + | "unsupported_method" + | "unsupported_amount" | "currency_mismatch" + | "amount_mismatch" | "merchant_mismatch" - | "cap_exceeded" - | "unsupported_amount", + | "cap_exceeded", message: string, ) { super(message); @@ -27,11 +28,7 @@ export class PaymentMismatchError extends Error { } function hostOf(value: string): string | undefined { - try { - return new URL(value.includes("://") ? value : `https://${value}`).hostname.toLowerCase(); - } catch { - return undefined; - } + return URL.parse(value.includes("://") ? value : `https://${value}`)?.hostname.toLowerCase(); } /** @@ -39,53 +36,34 @@ function hostOf(value: string): string | undefined { * 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 } { +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 new PaymentMismatchError( - "no_payment_request", - "Crossmint is not waiting for a payment on this checkout.", - ); + throw refuse("no_payment_request", "Crossmint is not waiting for a payment on this checkout."); } if (action.requestId !== approved.requestId) { - throw new PaymentMismatchError( - "request_changed", - "The payment request changed since approval. Show the person the new request.", - ); + 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.`); } - const { amount, merchant } = action.interaction; if (amount.kind !== "exact") { - throw new PaymentMismatchError( - "unsupported_amount", - "Crossmint sent a maximum rather than an exact total. Decline and ask the person how to proceed.", - ); + 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 new PaymentMismatchError("currency_mismatch", "The approved currency differs from Crossmint's."); + throw refuse("currency_mismatch", "The approved currency differs from Crossmint's."); } if (compareAmounts(amount.value, approved.amount) !== 0) { - throw new PaymentMismatchError( - "amount_mismatch", - `Crossmint is asking for ${amount.value} ${amount.currency}, not the approved amount.`, - ); + throw refuse("amount_mismatch", `Crossmint is asking for ${amount.value} ${amount.currency}, not the approved amount.`); } const liveHost = merchant.url ? hostOf(merchant.url) : undefined; - const approvedHost = hostOf(approved.merchant); - if (!liveHost || !approvedHost || liveHost !== approvedHost) { - throw new PaymentMismatchError( - "merchant_mismatch", - "The approved merchant differs from the one Crossmint is checking out at.", - ); + if (!liveHost || liveHost !== hostOf(approved.merchant)) { + throw refuse("merchant_mismatch", "The approved merchant differs from the one Crossmint is checking out at."); } if (record.maxCost.currency !== amount.currency || compareAmounts(amount.value, record.maxCost.amount) > 0) { - throw new PaymentMismatchError( - "cap_exceeded", - `The total exceeds the ${record.maxCost.amount} ${record.maxCost.currency} cap this checkout was started with.`, - ); + 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 index 485e824..2b03103 100644 --- a/server/crossmint/runs.ts +++ b/server/crossmint/runs.ts @@ -5,8 +5,8 @@ import type { MaxCost } from "./client"; * 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, like the Link sandbox request set. After a restart or a - * worker change an unfinished checkout is reconciled in the Crossmint console, not retried here. + * 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; diff --git a/tests/crossmint.test.ts b/tests/crossmint.test.ts index 8944b21..38b8ad5 100644 --- a/tests/crossmint.test.ts +++ b/tests/crossmint.test.ts @@ -1,5 +1,6 @@ -import { describe, expect, it, vi } from "vitest"; +import { afterEach, describe, expect, it, vi } from "vitest"; import { + AMOUNT, answerForm, assertCheckoutPolicy, cancelCheckout, @@ -19,6 +20,8 @@ import { } 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"; const config = { apiKey: "sk_unit_test_only", @@ -39,24 +42,30 @@ const snapshot = (overrides: Record) => ({ ...overrides, }); -const paymentRequest = (amount = "12.49", currency = "USD", url = "https://shop.example") => +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", - method: "card", 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); @@ -70,6 +79,7 @@ describe("Crossmint configuration", () => { 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"); @@ -90,11 +100,17 @@ describe("Crossmint configuration", () => { }); describe("Crossmint checkout policy", () => { - it("compares decimal amounts without floating point", () => { + 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", () => { @@ -104,7 +120,7 @@ describe("Crossmint checkout policy", () => { 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"]) { + 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); } }); @@ -134,11 +150,7 @@ describe("Crossmint client", () => { 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(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" } }, @@ -172,13 +184,11 @@ describe("Crossmint client", () => { 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].response).toEqual({ kind: "payment", orderIntentId: "oi_test_secret" }); + 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"); + await expect(payWithOrderIntent("run_1", "req_pay", { config: { ...config, orderIntentId: undefined }, fetch: fetcher })).rejects.toThrow("CROSSMINT_ORDER_INTENT_ID"); expect(fetcher).toHaveBeenCalledOnce(); }); @@ -186,7 +196,7 @@ describe("Crossmint client", () => { 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]).toMatchObject({ action: "decline", requestId: "req_1" }); + 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 }); @@ -197,9 +207,11 @@ describe("Crossmint client", () => { 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\.$/); @@ -219,7 +231,7 @@ describe("Crossmint snapshot projection", () => { expect(JSON.stringify(projected)).not.toContain("browser.example"); }); - it("projects a form request and keeps protected handling", () => { + it("projects form fields with Crossmint's input kinds, choice options, and protected handling", () => { const projected = projectCheckout( snapshot({ status: "awaiting_input", @@ -233,8 +245,24 @@ describe("Crossmint snapshot projection", () => { interaction: { kind: "form", fields: [ - { key: "size", label: "Size", required: true, handling: "standard", input: { type: "choice", choices: [{ value: "M", label: "Medium" }, "L"] } }, - { key: "otp", label: "Code", required: true, handling: "protected", input: { type: "text" } }, + { + 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" } }, ], }, }, @@ -248,14 +276,15 @@ describe("Crossmint snapshot projection", () => { interaction: { kind: "form", fields: [ - { key: "size", label: "Size", required: true, handling: "standard", type: "choice", choices: ["M", "L"] }, - { key: "otp", label: "Code", required: true, handling: "protected", type: "text" }, + { 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 amount and merchant only", () => { + 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); @@ -266,6 +295,9 @@ describe("Crossmint snapshot projection", () => { 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", () => { @@ -277,6 +309,8 @@ describe("Crossmint snapshot projection", () => { }), ).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"); @@ -285,6 +319,7 @@ describe("Crossmint snapshot projection", () => { it("rejects malformed snapshots", () => { expect(() => projectCheckout({ status: "running" })).toThrow(CrossmintRequestError); expect(() => projectCheckout(snapshot({ status: "exploded" }))).toThrow(CrossmintRequestError); + expect(() => projectCheckout("not json")).toThrow(CrossmintRequestError); }); }); @@ -301,8 +336,10 @@ describe("Crossmint payment cross-check", () => { it.each([ ["no_payment_request", approved, snapshot({ status: "running" })], ["request_changed", { ...approved, requestId: "req_old" }, paymentRequest()], - ["amount_mismatch", { ...approved, amount: "12.48" }, 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) => { @@ -315,20 +352,14 @@ describe("Crossmint payment cross-check", () => { expect(caught).toBeInstanceOf(PaymentMismatchError); expect((caught as PaymentMismatchError).reason).toBe(reason); }); - - it("refuses a maximum amount, which cannot be shown to the person as an exact total", () => { - const raw = paymentRequest(); - (raw.requiredAction as unknown as { request: { interaction: { amount: { kind: string } } } }).request.interaction.amount.kind = "maximum"; - expect(() => assertPaymentMatches(approved, live(raw), record)).toThrow(/maximum rather than an exact total/); - }); }); 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 }), - snapshot({ status: "awaiting_input", revision: 2, requiredAction: { requestId: "answered", request: { question: "old", interaction: { kind: "form", fields: [] } } } }), - snapshot({ status: "awaiting_input", revision: 3, requiredAction: { requestId: "req_new", request: { question: "new", interaction: { kind: "form", fields: [] } } } }), + 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" }); @@ -365,3 +396,57 @@ describe("Crossmint run registry", () => { 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); + }); +}); From 3a9249748be78da804fd70a1b69d6330d3958f7f Mon Sep 17 00:00:00 2001 From: Alejandro Dopico Date: Wed, 28 Oct 2026 17:58:54 -0500 Subject: [PATCH 3/4] Pay in Bell's browser with a Crossmint agent card Add crossmint_card_checkout. At the merchant's payment step the model maps the card inputs with exact CSS selectors and Eve asks the person to approve the amount and merchant. The server reads the operator's order intent and refuses unless it is active, scoped to this merchant, in this currency, with enough left, unexpired, and backed by an active Visa Intelligent Commerce or Mastercard Agent Pay rail. It then mints a one-time card with an idempotency key per tool call and fills it through the hosted-page path link__checkout uses. The card never leaves the fill. Order intents take a client key with the user's JWT, so Bell signs a ten-minute operator JWT and serves its public key at /api/crossmint/jwks. The browser privacy lock also engages when agent cards are configured, so the browser is quarantined after payment entry. CROSSMINT_ALLOWED_MERCHANTS and CROSSMINT_MAX_COST apply. --- .env.example | 9 + README.md | 2 +- agent/instructions.md | 9 + agent/lib/crossmint.ts | 9 + agent/tools/crossmint_card_checkout.ts | 108 +++++++ agent/tools/crossmint_pay.ts | 9 +- app/api/crossmint/jwks/route.ts | 15 + docs/crossmint.md | 219 +++++++++++++- docs/repository.md | 2 +- package.json | 1 + scripts/crossmint-operator-jwt.mjs | 15 + server/browser/privacy-lock.ts | 5 +- server/crossmint/cards.ts | 315 ++++++++++++++++++++ server/crossmint/operator-jwt.ts | 57 ++++ server/crossmint/payment.ts | 2 +- tests/crossmint-cards.test.ts | 395 +++++++++++++++++++++++++ 16 files changed, 1154 insertions(+), 18 deletions(-) create mode 100644 agent/tools/crossmint_card_checkout.ts create mode 100644 app/api/crossmint/jwks/route.ts create mode 100644 scripts/crossmint-operator-jwt.mjs create mode 100644 server/crossmint/cards.ts create mode 100644 server/crossmint/operator-jwt.ts create mode 100644 tests/crossmint-cards.test.ts diff --git a/.env.example b/.env.example index 3c884db..f8c1aad 100644 --- a/.env.example +++ b/.env.example @@ -77,3 +77,12 @@ CROSSMINT_ORDER_INTENT_ID= CROSSMINT_BUYER_PROFILE_ID= CROSSMINT_MAX_COST= CROSSMINT_ALLOWED_MERCHANTS= + +# Optional Crossmint Agent Cards: pay in this conversation's browser with a one-time card. Needs DATABASE_URL. +# Client key (ck_) with payment-methods.* and order-intents.* scopes; BELL_PUBLIC_URL must be an allowed origin. +CROSSMINT_CLIENT_API_KEY= +# Project id, and a base64 PEM RSA key that signs the operator JWT served at /api/crossmint/jwks. +CROSSMINT_PROJECT_ID= +CROSSMINT_JWT_PRIVATE_KEY= +# Exact payment-frame origins per merchant origin (JSON object). +CROSSMINT_CHECKOUT_ORIGINS={} diff --git a/README.md b/README.md index 3d03caf..60ca353 100644 --- a/README.md +++ b/README.md @@ -40,7 +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 | [Agent checkouts](docs/crossmint.md) | +| Crossmint | Buy at any store with the person's own card, worldwide, under a spending cap the person approves; 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 dd99a2e..a63d2ea 100644 --- a/agent/instructions.md +++ b/agent/instructions.md @@ -49,3 +49,12 @@ server verifies those values against Crossmint before paying. Call crossmint_che 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 index 87cb67d..dad6c56 100644 --- a/agent/lib/crossmint.ts +++ b/agent/lib/crossmint.ts @@ -1,3 +1,4 @@ +import type { ApprovalResponseContext, ApprovalResponseDecision } from "eve/tools/approval"; import { z } from "zod"; import { AMOUNT, @@ -26,6 +27,14 @@ export function notConfigured(): CheckoutToolOutput | undefined { return { status: "not_configured", hint: "Set CROSSMINT_SERVER_API_KEY and CROSSMINT_USER_ID on the server. See docs/crossmint.md." }; } +/** 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) { diff --git a/agent/tools/crossmint_card_checkout.ts b/agent/tools/crossmint_card_checkout.ts new file mode 100644 index 0000000..6d7f1d4 --- /dev/null +++ b/agent/tools/crossmint_card_checkout.ts @@ -0,0 +1,108 @@ +import { defineTool, toolOutput } from "eve/tools"; +import { always } from "eve/tools/approval"; +import { z } from "zod"; +import { amount, currency, errorOutput, 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 { 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 ${input.merchant} with a Crossmint agent card`, + }, + approval: { + request: always(), + prompt: ({ input }) => `Pay ${input.amount} ${input.currency} at ${input.merchant} 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; + 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); + // 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), () => mintCard(provider, payment, key, { config, signal }), 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.", + }; + } + return errorOutput(error); + } + }, + toModelOutput(output) { + return toolOutput.json(output); + }, +}); diff --git a/agent/tools/crossmint_pay.ts b/agent/tools/crossmint_pay.ts index 6c2c2c1..61386f8 100644 --- a/agent/tools/crossmint_pay.ts +++ b/agent/tools/crossmint_pay.ts @@ -1,7 +1,7 @@ import { defineTool, toolOutput } from "eve/tools"; import { always } from "eve/tools/approval"; import { z } from "zod"; -import { amount, currency, errorOutput, notConfigured, requestId, runId, WAIT_MS, type CheckoutToolOutput } from "../lib/crossmint"; +import { amount, currency, errorOutput, notConfigured, 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"; @@ -28,12 +28,7 @@ export default defineTool({ approval: { request: always(), prompt: ({ input }) => `Pay ${input.amount} ${input.currency} to ${input.merchant} with your Crossmint order intent?`, - response: ({ request, response }) => { - 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." }; - }, + response: requesterOnly, }, async execute(input, ctx): Promise { ctx.abortSignal.throwIfAborted(); 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/docs/crossmint.md b/docs/crossmint.md index d3ef6f5..1b93ace 100644 --- a/docs/crossmint.md +++ b/docs/crossmint.md @@ -1,4 +1,4 @@ -# Crossmint Agent Checkouts +# Crossmint Agent Commerce Toolkit Bell's `crossmint_checkout` and `crossmint_pay` tools buy through [Crossmint Agent Checkouts](https://docs.crossmint.com/agents/checkouts/overview), part of the @@ -15,9 +15,10 @@ Bell -> create run (URL, task, cap) -> Crossmint works through the store's check -> succeeded (receipt) -> Bell reports the order ``` -The checkout runs in Crossmint's service, not in this conversation's browser. Nothing in the Link -integration, the browser runtime, or the hooks changes. With the Crossmint variables unset, both -tools answer `not_configured`. +The checkout runs in Crossmint's service, not in this conversation's browser. 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 @@ -42,7 +43,8 @@ Create the key in the [Crossmint console](https://www.crossmint.com/console) wit `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, order intent, and receipt is scoped to it. +value is enough. Every run, order intent, and receipt is scoped to it. The order intent must belong +to the user that `CROSSMINT_USER_ID` names, or minting fails. `CROSSMINT_ORDER_INTENT_ID` is the budget the person approved in Crossmint beforehand. It names a saved card, an amount, a merchant scope, and an expiry. The card can be a Crossmint agent card, a card @@ -55,7 +57,8 @@ run up to the payment step and `crossmint_pay` answers `payment_not_configured`. 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, migration, or browser setting is involved. +Restart Bell after changing these values. Agent Checkouts needs no database, migration, or browser +setting. ## Try it in five minutes @@ -162,3 +165,207 @@ References: [Agent Checkouts overview](https://docs.crossmint.com/agents/checkou [pay for a checkout](https://docs.crossmint.com/agents/checkouts/payments), [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 Browserbase 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 order intent the person approved beforehand 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 above and adds these 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= +# Optional. Exact payment-frame origins per merchant origin, as a JSON object. +CROSSMINT_CHECKOUT_ORIGINS={} +DATABASE_URL= +``` + +Order intents accept a client key together with the user's JWT, not 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 the signature against the public key +Bell serves at `/api/crossmint/jwks`. Keep that path reachable over HTTPS without a login wall. It +serves only the public key. Every call carries the origin of `BELL_PUBLIC_URL`, which must be an +allowed origin of the client 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' +``` + +Register Bell as the project's custom JWT provider, with the +[Crossmint CLI](https://docs.crossmint.com/cli/projects/auth-provider) or the console's JWT +authentication settings: + +```sh +crossmint projects auth-provider set --provider custom --jwks-uri https:///api/crossmint/jwks --issuer +``` + +A project has one auth provider, so give Bell a Crossmint project of its own. + +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 the card settings present, 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 + +The person saves the card, registers it, and approves an order intent in Crossmint's card +components, signed in with Bell's operator token. Crossmint's +[Agent Cards reference app](https://github.com/Crossmint/card-permissions-quickstart) does this once +its sign-in is replaced with a token from: + +```sh +pnpm crossmint:operator-jwt +``` + +The command prints a token valid for ten minutes. Treat it like a password until it expires. The +reference app's origin must also be an allowed origin of the client key. + +1. Save the card. +2. Register it for agent payments. Registration finds the card's network rail and grants nothing. +3. Create an order intent with an amount, an expiry, and the merchant's name, HTTPS URL, and + country. Bell refuses an order intent that names no merchant. +4. Verify the card rail. Visa sends a one-time code and asks for a passkey. Mastercard opens a + hosted page. Wait until the `agentic-token` rail reads `active`. +5. Set `CROSSMINT_ORDER_INTENT_ID` in `.env.local` to the order intent id and restart Bell. + +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: a network token needs a +payment processor integration, and the encrypted card returns the real card number. + +### 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, verify the operator token against the JWKS, and check that no card +value or Crossmint message reaches tool output. No test calls Crossmint. + +The staging smoke below has not been run for this change. It needs a staging project with Bell's +JWKS reachable over HTTPS, through a tunnel when Bell runs locally, `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`, register it, approve a 10.00 USD order intent 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}' + ``` + + The same call with `X-API-KEY: $CROSSMINT_SERVER_API_KEY` and no token should answer 401 or 403. +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), +[custom JWT authentication](https://docs.crossmint.com/introduction/platform/api-keys/custom-jwt-auth-guide). diff --git a/docs/repository.md b/docs/repository.md index 47eb6ce..6970efe 100644 --- a/docs/repository.md +++ b/docs/repository.md @@ -33,7 +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), [shared tool helpers](../agent/lib/crossmint.ts), [server client](../server/crossmint/client.ts), [payment cross-check](../server/crossmint/payment.ts) | [Agent checkouts](crossmint.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), [agent cards](../server/crossmint/cards.ts), [operator JWT](../server/crossmint/operator-jwt.ts) and its [JWKS route](../app/api/crossmint/jwks/route.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..756598b 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": { 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/server/browser/privacy-lock.ts b/server/browser/privacy-lock.ts index f53ca7d..57b3a40 100644 --- a/server/browser/privacy-lock.ts +++ b/server/browser/privacy-lock.ts @@ -1,5 +1,6 @@ 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>(); @@ -27,8 +28,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..4099ef9 --- /dev/null +++ b/server/crossmint/cards.ts @@ -0,0 +1,315 @@ +import { createHash, type KeyObject } from "node:crypto"; +import { z } from "zod"; +import { + compareAmounts, + crossmintConfig, + CrossmintRequestError, + CrossmintSetupError, + isCrossmintConfigured, + type CrossmintConfig, + type MaxCost, +} from "./client"; +import { operatorJwt, parseRsaPrivateKey } from "./operator-jwt"; +import { hostOf } from "./payment"; + +/** + * Crossmint Agent Cards, server side. + * + * The person approves an order intent in Crossmint 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 CrossmintConfig { + /** Client key (ck_). Order intents accept a client key with the user's JWT, not a server key. */ + clientApiKey: string; + /** Crossmint project id, the `iss` of the operator JWT. */ + projectId: string; + privateKey: KeyObject; + /** Bell's origin, sent with every call. It must be an allowed origin of the client key. */ + origin: string; + /** Payment-frame origins trusted per merchant origin, such as a payment provider's card iframe. */ + checkoutOrigins: Record; +} + +export function isCrossmintCardsConfigured(env: Record = process.env): boolean { + return isCrossmintConfigured(env) && Boolean(env.CROSSMINT_CLIENT_API_KEY?.trim() && env.CROSSMINT_JWT_PRIVATE_KEY?.trim()); +} + +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 = 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"); + + let checkoutOrigins: Record; + try { + checkoutOrigins = z.record(z.string(), z.array(z.string())).parse(JSON.parse(env.CROSSMINT_CHECKOUT_ORIGINS?.trim() || "{}")); + } catch { + throw invalid("CROSSMINT_CHECKOUT_ORIGINS"); + } + if (Object.entries(checkoutOrigins).some(([merchant, origins]) => !exactHttpsOrigin(merchant) || !origins.every(exactHttpsOrigin))) { + throw invalid("CROSSMINT_CHECKOUT_ORIGINS"); + } + + return { ...base, clientApiKey, projectId, privateKey, origin: publicUrl.origin, 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.", +} 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; +} + +const REQUEST_TIMEOUT_MS = 20_000; + +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. */ +export async function cardRequest( + path: string, + init: { method: "GET" | "POST" | "PUT"; body?: unknown; idempotencyKey?: string }, + options: CardClientOptions = {}, +): Promise { + const config = options.config ?? cardConfig(); + 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.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"); + } + 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/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/payment.ts b/server/crossmint/payment.ts index bcff283..3629d11 100644 --- a/server/crossmint/payment.ts +++ b/server/crossmint/payment.ts @@ -27,7 +27,7 @@ export class PaymentMismatchError extends Error { } } -function hostOf(value: string): string | undefined { +export function hostOf(value: string): string | undefined { return URL.parse(value.includes("://") ? value : `https://${value}`)?.hostname.toLowerCase(); } diff --git a/tests/crossmint-cards.test.ts b/tests/crossmint-cards.test.ts new file mode 100644 index 0000000..5e9f9bf --- /dev/null +++ b/tests/crossmint-cards.test.ts @@ -0,0 +1,395 @@ +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 { 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"] }), + 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", () => { + expect(isCrossmintCardsConfigured({})).toBe(false); + expect(isCrossmintCardsConfigured({ ...env, CROSSMINT_CLIENT_API_KEY: "" })).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?"); + 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"); + }); +}); + +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."); + }); +}); From 1b43c0bb2e0d313af6f2d0141ea6652e7c1312f3 Mon Sep 17 00:00:00 2001 From: Alejandro Dopico Date: Wed, 28 Oct 2026 17:59:04 -0500 Subject: [PATCH 4/4] Add an operator page to set up a Crossmint agent card /crossmint/cards renders Crossmint's CrossmintAgentCardAuthorization component behind Bell's operator credentials. It saves or selects the card, registers it, creates an order intent for one merchant, verifies the card rail, and shows the order intent id to paste into .env.local. A root proxy asks for the credentials. This adds @crossmint/client-sdk-react-ui 4.12.1, which carries wallet and chain dependencies the page does not use. Drop this commit to keep the dependency tree as it is. --- app/crossmint/cards/card-setup.tsx | 113 + app/crossmint/cards/page.tsx | 46 + docs/crossmint.md | 7 + package.json | 1 + pnpm-lock.yaml | 6896 +++++++++++++++++++++++++++- proxy.ts | 12 + tests/crossmint-card-setup.test.ts | 81 + 7 files changed, 7031 insertions(+), 125 deletions(-) create mode 100644 app/crossmint/cards/card-setup.tsx create mode 100644 app/crossmint/cards/page.tsx create mode 100644 proxy.ts create mode 100644 tests/crossmint-card-setup.test.ts diff --git a/app/crossmint/cards/card-setup.tsx b/app/crossmint/cards/card-setup.tsx new file mode 100644 index 0000000..e761191 --- /dev/null +++ b/app/crossmint/cards/card-setup.tsx @@ -0,0 +1,113 @@ +"use client"; + +import { CrossmintAgentCardAuthorization, CrossmintProvider, type AgentCardAuthorizationResult } from "@crossmint/client-sdk-react-ui"; +import { useState, type FormEvent } from "react"; + +interface Budget { + amount: { value: string; currency: string }; + merchant: { name: string; url: string; countryCode: string }; + description: string; + expiresAt: string; +} + +// Crossmint's component selects or saves the card, registers it, creates the order intent, and +// runs the card network's verification. Card details never reach this page. +export default function CardSetup({ apiKey, jwt }: { apiKey: string; jwt: string }) { + const [budget, setBudget] = useState(); + const [result, setResult] = useState(); + const [error, setError] = useState(""); + + function approve(event: FormEvent) { + event.preventDefault(); + const form = new FormData(event.currentTarget); + const text = (name: string) => String(form.get(name) ?? "").trim(); + setError(""); + setBudget({ + amount: { value: text("amount"), currency: text("currency").toUpperCase() }, + merchant: { name: text("merchantName"), url: text("merchantUrl"), countryCode: text("merchantCountry").toUpperCase() }, + description: text("description"), + expiresAt: new Date(Date.now() + Number(text("days")) * 86_400_000).toISOString(), + }); + } + + if (result) { + const network = result.rail.rail === "agentic-token"; + return ( +
+

Order intent approved

+

+ {result.paymentMethod.brand} ending {result.paymentMethod.last4}, {result.amount.available} {result.amount.currency} available + until {new Date(result.expiresAt).toLocaleString()}. +

+ {network ? ( +

Rail: {result.rail.rail} ({result.rail.provider}). crossmint_card_checkout can pay with it.

+ ) : ( +

+ This card has no Visa Intelligent Commerce or Mastercard Agent Pay rail, so crossmint_card_checkout cannot pay with it. + Agent Checkouts can. +

+ )} +

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

+
CROSSMINT_ORDER_INTENT_ID={result.orderIntentId}
+
+ ); + } + + if (budget) { + return ( + + { + setError(`${failure.code}: ${failure.message}`); + setBudget(undefined); + }} + /> + + ); + } + + return ( +
+ {error ?

{error}

: null} +
+ Budget + + + + +
+
+ Merchant + + + +
+ +
+ ); +} diff --git a/app/crossmint/cards/page.tsx b/app/crossmint/cards/page.tsx new file mode 100644 index 0000000..eeb7aac --- /dev/null +++ b/app/crossmint/cards/page.tsx @@ -0,0 +1,46 @@ +import { routeAuth } from "eve/channels/auth"; +import { headers } from "next/headers"; +import { CrossmintSetupError } from "../../../server/crossmint/client"; +import { cardConfig } from "../../../server/crossmint/cards"; +import { operatorJwt } from "../../../server/crossmint/operator-jwt"; +import { operatorAuth } from "../../../server/operator-auth"; +import CardSetup from "./card-setup"; + +export const dynamic = "force-dynamic"; + +// Operator only. proxy.ts asks for the credentials; this checks again before signing a token. +export default async function CrossmintCardsPage() { + 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/cards`, { headers: incoming }), [operatorAuth]); + if (auth instanceof Response) { + return

Sign in as the Bell operator to set up a Crossmint agent card.

; + } + + let setup: { apiKey: string; jwt: string } | { error: string }; + try { + const config = cardConfig(); + setup = { apiKey: config.clientApiKey, jwt: operatorJwt(config) }; + } catch (error) { + if (!(error instanceof CrossmintSetupError)) throw error; + setup = { error: `${error.message} See docs/crossmint.md.` }; + } + + return ( +
+
+
+

Crossmint

+

Agent card setup

+
+
+

+ Save your card, register it, approve an order intent for one merchant, and verify the card rail. Then paste + the order intent id into .env.local and restart Bell. This page signs you in to Crossmint for ten minutes; + reload it to continue after that. +

+ {"error" in setup ?

{setup.error}

: } +
+ ); +} diff --git a/docs/crossmint.md b/docs/crossmint.md index 1b93ace..05e1606 100644 --- a/docs/crossmint.md +++ b/docs/crossmint.md @@ -253,6 +253,13 @@ pnpm crossmint:operator-jwt The command prints a token valid for ten minutes. Treat it like a password until it expires. The reference app's origin must also be an allowed origin of the client key. +Bell also serves the setup at `/crossmint/cards`, for the operator only: it asks for +`BELL_OPERATOR_USERNAME` and `BELL_OPERATOR_PASSWORD`, also when Bell runs locally. The page renders +Crossmint's `CrossmintAgentCardAuthorization` component, which selects or saves the card, registers +it, creates the order intent, and runs the rail verification, then shows the line to paste into +`.env.local`. The page pulls in Crossmint's React SDK, which carries wallet and chain dependencies +the card page does not use. + 1. Save the card. 2. Register it for agent payments. Registration finds the card's network rail and grants nothing. 3. Create an order intent with an amount, an expiry, and the merchant's name, HTTPS URL, and diff --git a/package.json b/package.json index 756598b..cbd3a88 100644 --- a/package.json +++ b/package.json @@ -26,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..5287198 --- /dev/null +++ b/proxy.ts @@ -0,0 +1,12 @@ +import { routeAuth } from "eve/channels/auth"; +import { NextResponse } from "next/server"; +import { operatorAuth } from "./server/operator-auth"; + +// The Crossmint card setup page is for the operator only. Asking here lets the browser show its +// HTTP Basic prompt; the page and its action route check again. +export async function proxy(request: Request) { + const auth = await routeAuth(request, [operatorAuth]); + return auth instanceof Response ? auth : NextResponse.next(); +} + +export const config = { matcher: ["/crossmint/:path*"] }; diff --git a/tests/crossmint-card-setup.test.ts b/tests/crossmint-card-setup.test.ts new file mode 100644 index 0000000..9a05c14 --- /dev/null +++ b/tests/crossmint-card-setup.test.ts @@ -0,0 +1,81 @@ +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 CrossmintCardsPage from "../app/crossmint/cards/page.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/cards/card-setup", () => ({ default: function CardSetup() { 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"), + BELL_PUBLIC_URL: "https://bell.example", +}; + +function find(node: ReactNode, name: string): ReactElement> | undefined { + if (Array.isArray(node)) return node.map((child) => find(child, name)).find(Boolean); + if (!isValidElement<{ children?: ReactNode }>(node)) return undefined; + if (typeof node.type === "function" && node.type.name === name) return node as ReactElement>; + return find(node.props.children, name); +} + +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()); + +describe("Crossmint card setup access", () => { + it("covers only the setup page", () => { + 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/cards")); + 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/cards", { headers: { authorization: basic } })); + expect(allowed.headers.get("x-middleware-next")).toBe("1"); + const crossOrigin = await proxy(new Request("https://bell.example/crossmint/cards", { 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 CrossmintCardsPage(); + expect(find(page, "CardSetup")).toBeUndefined(); + expect(JSON.stringify(page)).not.toContain("ck_production_unit_test_only"); + }); + + it("gives the browser only the client key and a ten-minute operator token", async () => { + incoming.headers.set("authorization", basic); + const setup = find(await CrossmintCardsPage(), "CardSetup"); + expect(Object.keys(setup?.props ?? {}).sort()).toEqual(["apiKey", "jwt"]); + const { apiKey, jwt } = setup!.props as { apiKey: string; jwt: string }; + expect(apiKey).toBe("ck_production_unit_test_only"); + const [header, payload, signature] = 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("names a missing setting instead of rendering the card form", async () => { + incoming.headers.set("authorization", basic); + vi.stubEnv("CROSSMINT_PROJECT_ID", ""); + const page = await CrossmintCardsPage(); + expect(find(page, "CardSetup")).toBeUndefined(); + expect(JSON.stringify(page)).toContain("CROSSMINT_PROJECT_ID"); + }); +});