diff --git a/.changeset/some-moons-burn.md b/.changeset/some-moons-burn.md new file mode 100644 index 00000000000..cdb5a989c3a --- /dev/null +++ b/.changeset/some-moons-burn.md @@ -0,0 +1,5 @@ +--- +"thirdweb": minor +--- + +Accept arbitrary chain ids for x402 payments with new verifyPayment() backend utility diff --git a/apps/playground-web/package.json b/apps/playground-web/package.json index 38c353e8bb1..35764a3b1fd 100644 --- a/apps/playground-web/package.json +++ b/apps/playground-web/package.json @@ -48,7 +48,6 @@ "thirdweb": "workspace:*", "use-debounce": "^10.0.5", "use-stick-to-bottom": "^1.1.1", - "x402-next": "^0.6.1", "zod": "3.25.75" }, "devDependencies": { diff --git a/apps/playground-web/src/app/payments/x402/components/x402-client-preview.tsx b/apps/playground-web/src/app/payments/x402/components/x402-client-preview.tsx index 55597040afd..53767c02265 100644 --- a/apps/playground-web/src/app/payments/x402/components/x402-client-preview.tsx +++ b/apps/playground-web/src/app/payments/x402/components/x402-client-preview.tsx @@ -3,7 +3,7 @@ import { useMutation } from "@tanstack/react-query"; import { CodeClient } from "@workspace/ui/components/code/code.client"; import { CodeIcon, LockIcon } from "lucide-react"; -import { baseSepolia } from "thirdweb/chains"; +import { arbitrumSepolia } from "thirdweb/chains"; import { ConnectButton, getDefaultToken, @@ -15,7 +15,7 @@ import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { THIRDWEB_CLIENT } from "../../../../lib/client"; -const chain = baseSepolia; +const chain = arbitrumSepolia; const token = getDefaultToken(chain, "USDC"); export function X402ClientPreview() { diff --git a/apps/playground-web/src/app/payments/x402/page.tsx b/apps/playground-web/src/app/payments/x402/page.tsx index 427813f5b4f..36d7f4b416a 100644 --- a/apps/playground-web/src/app/payments/x402/page.tsx +++ b/apps/playground-web/src/app/payments/x402/page.tsx @@ -46,8 +46,8 @@ function ServerCodeExample() { Next.js Server Code Example

- Use any x402 middleware + the thirdweb facilitator to settle - transactions with our server wallet. + Create middleware with the thirdweb facilitator to settle transactions + with your server wallet.

@@ -57,28 +57,45 @@ function ServerCodeExample() { className="h-full rounded-none border-none" code={`// src/middleware.ts -import { facilitator } from "thirdweb/x402"; +import { facilitator, verifyPayment } from "thirdweb/x402"; import { createThirdwebClient } from "thirdweb"; import { paymentMiddleware } from "x402-next"; const client = createThirdwebClient({ secretKey: "your-secret-key" }); +const thirdwebX402Facilitator = facilitator({ + client, + serverWalletAddress: "0xYourWalletAddress", +}); + +export async function middleware(request: NextRequest) { + const method = request.method.toUpperCase(); + const resourceUrl = request.nextUrl.toString(); + const paymentData = request.headers.get("X-PAYMENT"); -export const middleware = paymentMiddleware( - "0xYourWalletAddress", - { - "/api/paid-endpoint": { - price: "$0.01", - network: "base-sepolia", - config: { - description: "Access to paid content", - }, + const result = await verifyPayment({ + resourceUrl, + method, + paymentData, + payTo: "0xYourWalletAddress", + network: "eip155:11155111", // or any other chain id + price: "$0.01", // can also be a ERC20 token amount + routeConfig: { + description: "Access to paid content", }, - }, - facilitator({ - client, - serverWalletAddress: "0xYourServerWalletAddress", - }), -); + facilitator: thirdwebX402Facilitator, + }); + + if (result.status === 200) { + // payment successful, execute the request + return NextResponse.next(); + } + + // otherwise, request payment + return NextResponse.json(result.responseBody, { + status: result.status, + headers: result.responseHeaders, + }); +} // Configure which paths the middleware should run on export const config = { diff --git a/apps/playground-web/src/middleware.ts b/apps/playground-web/src/middleware.ts index 047222743fe..c4a440d067a 100644 --- a/apps/playground-web/src/middleware.ts +++ b/apps/playground-web/src/middleware.ts @@ -1,34 +1,59 @@ +import { type NextRequest, NextResponse } from "next/server"; import { createThirdwebClient } from "thirdweb"; -import { facilitator } from "thirdweb/x402"; -import { paymentMiddleware } from "x402-next"; +import { arbitrumSepolia } from "thirdweb/chains"; +import { facilitator, verifyPayment } from "thirdweb/x402"; const client = createThirdwebClient({ secretKey: process.env.THIRDWEB_SECRET_KEY as string, }); +const chain = arbitrumSepolia; const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_WALLET as string; const ENGINE_VAULT_ACCESS_TOKEN = process.env .ENGINE_VAULT_ACCESS_TOKEN as string; const API_URL = `https://${process.env.NEXT_PUBLIC_API_URL || "api.thirdweb.com"}`; -export const middleware = paymentMiddleware( - "0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024", - { - "/api/paywall": { - price: "$0.01", - network: "base-sepolia", - config: { - description: "Access to paid content", - }, +const twFacilitator = facilitator({ + baseUrl: `${API_URL}/v1/payments/x402`, + client, + serverWalletAddress: BACKEND_WALLET_ADDRESS, + vaultAccessToken: ENGINE_VAULT_ACCESS_TOKEN, +}); + +export async function middleware(request: NextRequest) { + const pathname = request.nextUrl.pathname; + const method = request.method.toUpperCase(); + const resourceUrl = `${request.nextUrl.protocol}//${request.nextUrl.host}${pathname}`; + const paymentData = request.headers.get("X-PAYMENT"); + + const result = await verifyPayment({ + resourceUrl, + method, + paymentData, + payTo: "0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024", + network: `eip155:${chain.id}`, + price: "$0.01", + routeConfig: { + description: "Access to paid content", }, - }, - facilitator({ - baseUrl: `${API_URL}/v1/payments/x402`, - client, - serverWalletAddress: BACKEND_WALLET_ADDRESS, - vaultAccessToken: ENGINE_VAULT_ACCESS_TOKEN, - }), -); + facilitator: twFacilitator, + }); + + if (result.status === 200) { + // payment successful, execute the request + const response = NextResponse.next(); + for (const [key, value] of Object.entries(result.responseHeaders)) { + response.headers.set(key, value); + } + return response; + } + + // otherwise, request payment + return NextResponse.json(result.responseBody, { + status: result.status, + headers: result.responseHeaders, + }); +} // Configure which paths the middleware should run on export const config = { diff --git a/apps/portal/src/app/payments/x402/page.mdx b/apps/portal/src/app/payments/x402/page.mdx index 935a5853955..6506d94e5fe 100644 --- a/apps/portal/src/app/payments/x402/page.mdx +++ b/apps/portal/src/app/payments/x402/page.mdx @@ -41,37 +41,57 @@ const response = await fetchWithPay('https://api.example.com/paid-endpoint'); ## Server Side -To make your API calls payable, you can use any x402 middleware library like x402-hono, x402-next, x402-express, etc. +To make your API calls payable, you can use the `verifyPayment` function in a simple middleware or in your endpoint directly. -Then, use the `facilitator` configuratino function settle transactions with your thirdweb server wallet gaslessly and pass it to the middleware. +Use the `facilitator` configuration function settle transactions with your thirdweb server wallet gaslessly and pass it to the `verifyPayment` function. -Here's an example with Next.js: +Here's an example with a Next.js middleware: ```typescript import { createThirdwebClient } from "thirdweb"; -import { facilitator } from "thirdweb/x402"; +import { facilitator, verifyPayment } from "thirdweb/x402"; import { paymentMiddleware } from "x402-next"; -const client = createThirdwebClient({ - secretKey: process.env.THIRDWEB_SECRET_KEY as string, +const client = createThirdwebClient({ secretKey: "your-secret-key" }); +const thirdwebX402Facilitator = facilitator({ + client, + serverWalletAddress: "0xYourWalletAddress", }); -export const middleware = paymentMiddleware( - "0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024", - { - "/api/paid-endpoint": { - price: "$0.01", - network: "base-sepolia", - config: { - description: "Access to paid content", - }, +export async function middleware(request: NextRequest) { + const method = request.method.toUpperCase(); + const resourceUrl = request.nextUrl.toString(); + const paymentData = request.headers.get("X-PAYMENT"); + + const result = await verifyPayment({ + resourceUrl, + method, + paymentData, + payTo: "0xYourWalletAddress", + network: "eip155:1", // or any other chain id in CAIP2 format: "eip155:" + price: "$0.01", // can also be a ERC20 token amount + routeConfig: { + description: "Access to paid content", }, - }, - facilitator({ - client, - serverWalletAddress: "0x1234567890123456789012345678901234567890", - }), -); + facilitator: thirdwebX402Facilitator, + }); + + if (result.status === 200) { + // payment successful, execute the request + const response = NextResponse.next(); + // optionally set the response headers back to the client + for (const [key, value] of Object.entries(result.responseHeaders)) { + response.headers.set(key, value); + } + return response; + } + + // otherwise, request payment + return NextResponse.json(result.responseBody, { + status: result.status, + headers: result.responseHeaders, + }); +} // Configure which paths the middleware should run on export const config = { diff --git a/packages/thirdweb/src/exports/x402.ts b/packages/thirdweb/src/exports/x402.ts index ee3f36de0bd..0439de7cc48 100644 --- a/packages/thirdweb/src/exports/x402.ts +++ b/packages/thirdweb/src/exports/x402.ts @@ -1,5 +1,11 @@ +export { decodePayment, encodePayment } from "../x402/encode.js"; export { facilitator, type ThirdwebX402FacilitatorConfig, } from "../x402/facilitator.js"; export { wrapFetchWithPayment } from "../x402/fetchWithPayment.js"; +export { + type VerifyPaymentArgs, + type VerifyPaymentResult, + verifyPayment, +} from "../x402/verify-payment.js"; diff --git a/packages/thirdweb/src/react/core/utils/defaultTokens.ts b/packages/thirdweb/src/react/core/utils/defaultTokens.ts index ed92560b5ac..eaae86fb549 100644 --- a/packages/thirdweb/src/react/core/utils/defaultTokens.ts +++ b/packages/thirdweb/src/react/core/utils/defaultTokens.ts @@ -289,15 +289,9 @@ const DEFAULT_TOKENS = { symbol: "USDC", }, ], - "421613": [ + "421614": [ { - address: "0xe39Ab88f8A4777030A534146A9Ca3B52bd5D43A3", - icon: wrappedEthIcon, - name: "Wrapped Ether", - symbol: "WETH", - }, - { - address: "0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63", + address: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d", icon: usdcIcon, name: "USD Coin", symbol: "USDC", diff --git a/packages/thirdweb/src/x402/encode.ts b/packages/thirdweb/src/x402/encode.ts new file mode 100644 index 00000000000..17567c5af8b --- /dev/null +++ b/packages/thirdweb/src/x402/encode.ts @@ -0,0 +1,81 @@ +import type { ExactEvmPayload } from "x402/types"; +import { + type RequestedPaymentPayload, + RequestedPaymentPayloadSchema, +} from "./schemas.js"; + +/** + * Encodes a payment payload into a base64 string, ensuring bigint values are properly stringified + * + * @param payment - The payment payload to encode + * @returns A base64 encoded string representation of the payment payload + */ +export function encodePayment(payment: RequestedPaymentPayload): string { + let safe: RequestedPaymentPayload; + + // evm + const evmPayload = payment.payload as ExactEvmPayload; + safe = { + ...payment, + payload: { + ...evmPayload, + authorization: Object.fromEntries( + Object.entries(evmPayload.authorization).map(([key, value]) => [ + key, + typeof value === "bigint" ? (value as bigint).toString() : value, + ]), + ) as ExactEvmPayload["authorization"], + }, + }; + return safeBase64Encode(JSON.stringify(safe)); +} + +/** + * Decodes a base64 encoded payment string back into a PaymentPayload object + * + * @param payment - The base64 encoded payment string to decode + * @returns The decoded and validated PaymentPayload object + */ +export function decodePayment(payment: string): RequestedPaymentPayload { + const decoded = safeBase64Decode(payment); + const parsed = JSON.parse(decoded); + + const obj: RequestedPaymentPayload = { + ...parsed, + payload: parsed.payload as ExactEvmPayload, + }; + const validated = RequestedPaymentPayloadSchema.parse(obj); + return validated; +} + +/** + * Encodes a string to base64 format + * + * @param data - The string to be encoded to base64 + * @returns The base64 encoded string + */ +export function safeBase64Encode(data: string): string { + if ( + typeof globalThis !== "undefined" && + typeof globalThis.btoa === "function" + ) { + return globalThis.btoa(data); + } + return Buffer.from(data).toString("base64"); +} + +/** + * Decodes a base64 string back to its original format + * + * @param data - The base64 encoded string to be decoded + * @returns The decoded string in UTF-8 format + */ +function safeBase64Decode(data: string): string { + if ( + typeof globalThis !== "undefined" && + typeof globalThis.atob === "function" + ) { + return globalThis.atob(data); + } + return Buffer.from(data, "base64").toString("utf-8"); +} diff --git a/packages/thirdweb/src/x402/facilitator.ts b/packages/thirdweb/src/x402/facilitator.ts index da303e98e9b..8db39bfd0e7 100644 --- a/packages/thirdweb/src/x402/facilitator.ts +++ b/packages/thirdweb/src/x402/facilitator.ts @@ -1,5 +1,12 @@ -import type { FacilitatorConfig } from "x402/types"; +import type { SupportedPaymentKindsResponse, VerifyResponse } from "x402/types"; import type { ThirdwebClient } from "../client/client.js"; +import { stringify } from "../utils/json.js"; +import { withCache } from "../utils/promise/withCache.js"; +import type { + FacilitatorSettleResponse, + RequestedPaymentPayload, + RequestedPaymentRequirements, +} from "./schemas.js"; export type ThirdwebX402FacilitatorConfig = { client: ThirdwebClient; @@ -12,7 +19,7 @@ const DEFAULT_BASE_URL = "https://api.thirdweb.com/v1/payments/x402"; /** * Creates a facilitator for the x402 payment protocol. - * Use this with any x402 middleware to enable settling transactions with your thirdweb server wallet. + * You can use this with `verifyPayment` or with any x402 middleware to enable settling transactions with your thirdweb server wallet. * * @param config - The configuration for the facilitator * @returns a x402 compatible FacilitatorConfig @@ -48,9 +55,7 @@ const DEFAULT_BASE_URL = "https://api.thirdweb.com/v1/payments/x402"; * * @bridge x402 */ -export function facilitator( - config: ThirdwebX402FacilitatorConfig, -): FacilitatorConfig { +export function facilitator(config: ThirdwebX402FacilitatorConfig) { const secretKey = config.client.secretKey; if (!secretKey) { throw new Error("Client secret key is required for the x402 facilitator"); @@ -61,7 +66,7 @@ export function facilitator( "Server wallet address is required for the x402 facilitator", ); } - return { + const facilitator = { url: (config.baseUrl ?? DEFAULT_BASE_URL) as `${string}://${string}`, createAuthHeaders: async () => { return { @@ -83,5 +88,108 @@ export function facilitator( }, }; }, + /** + * Verifies a payment payload with the facilitator service + * + * @param payload - The payment payload to verify + * @param paymentRequirements - The payment requirements to verify against + * @returns A promise that resolves to the verification response + */ + async verify( + payload: RequestedPaymentPayload, + paymentRequirements: RequestedPaymentRequirements, + ): Promise { + const url = config.baseUrl ?? DEFAULT_BASE_URL; + + let headers = { "Content-Type": "application/json" }; + const authHeaders = await facilitator.createAuthHeaders(); + headers = { ...headers, ...authHeaders.verify }; + + const res = await fetch(`${url}/verify`, { + method: "POST", + headers, + body: stringify({ + x402Version: payload.x402Version, + paymentPayload: payload, + paymentRequirements: paymentRequirements, + }), + }); + + if (res.status !== 200) { + const text = `${res.statusText} ${await res.text()}`; + throw new Error(`Failed to verify payment: ${res.status} ${text}`); + } + + const data = await res.json(); + return data as VerifyResponse; + }, + + /** + * Settles a payment with the facilitator service + * + * @param payload - The payment payload to settle + * @param paymentRequirements - The payment requirements for the settlement + * @returns A promise that resolves to the settlement response + */ + async settle( + payload: RequestedPaymentPayload, + paymentRequirements: RequestedPaymentRequirements, + ): Promise { + const url = config.baseUrl ?? DEFAULT_BASE_URL; + + let headers = { "Content-Type": "application/json" }; + const authHeaders = await facilitator.createAuthHeaders(); + headers = { ...headers, ...authHeaders.settle }; + + const res = await fetch(`${url}/settle`, { + method: "POST", + headers, + body: JSON.stringify({ + x402Version: payload.x402Version, + paymentPayload: payload, + paymentRequirements: paymentRequirements, + }), + }); + + if (res.status !== 200) { + const text = `${res.statusText} ${await res.text()}`; + throw new Error(`Failed to settle payment: ${res.status} ${text}`); + } + + const data = await res.json(); + return data as FacilitatorSettleResponse; + }, + + /** + * Gets the supported payment kinds from the facilitator service. + * + * @returns A promise that resolves to the supported payment kinds + */ + async supported(): Promise { + const url = config.baseUrl ?? DEFAULT_BASE_URL; + return withCache( + async () => { + let headers = { "Content-Type": "application/json" }; + const authHeaders = await facilitator.createAuthHeaders(); + headers = { ...headers, ...authHeaders.supported }; + const res = await fetch(`${url}/supported`, { headers }); + + if (res.status !== 200) { + throw new Error( + `Failed to get supported payment kinds: ${res.statusText}`, + ); + } + + const data = await res.json(); + return data as SupportedPaymentKindsResponse; + }, + { + cacheKey: `supported-payment-kinds-${url}`, + cacheTime: 1000 * 60 * 60 * 24, // 24 hours + }, + ); + }, }; + + return facilitator; } diff --git a/packages/thirdweb/src/x402/fetchWithPayment.ts b/packages/thirdweb/src/x402/fetchWithPayment.ts index cdf8a141de3..d978e837e63 100644 --- a/packages/thirdweb/src/x402/fetchWithPayment.ts +++ b/packages/thirdweb/src/x402/fetchWithPayment.ts @@ -1,15 +1,13 @@ -import { createPaymentHeader } from "x402/client"; -import { - ChainIdToNetwork, - EvmNetworkToChainId, - type PaymentRequirements, - PaymentRequirementsSchema, - type Signer, -} from "x402/types"; -import { viemAdapter } from "../adapters/viem.js"; +import { ChainIdToNetwork } from "x402/types"; import { getCachedChain } from "../chains/utils.js"; import type { ThirdwebClient } from "../client/client.js"; import type { Wallet } from "../wallets/interfaces/wallet.js"; +import { + networkToChainId, + type RequestedPaymentRequirements, + RequestedPaymentRequirementsSchema, +} from "./schemas.js"; +import { createPaymentHeader } from "./sign.js"; /** * Enables the payment of APIs using the x402 payment protocol. @@ -52,7 +50,7 @@ import type { Wallet } from "../wallets/interfaces/wallet.js"; */ export function wrapFetchWithPayment( fetch: typeof globalThis.fetch, - client: ThirdwebClient, + _client: ThirdwebClient, wallet: Wallet, maxValue: bigint = BigInt(1 * 10 ** 6), // Default to 1 USDC ) { @@ -68,7 +66,7 @@ export function wrapFetchWithPayment( accepts: unknown[]; }; const parsedPaymentRequirements = accepts - .map((x) => PaymentRequirementsSchema.parse(x)) + .map((x) => RequestedPaymentRequirementsSchema.parse(x)) .filter((x) => x.scheme === "exact"); // TODO (402): accept other schemes const account = wallet.getAccount(); @@ -89,16 +87,10 @@ export function wrapFetchWithPayment( throw new Error("Payment amount exceeds maximum allowed"); } - const paymentChainId = EvmNetworkToChainId.get( + const paymentChainId = networkToChainId( selectedPaymentRequirements.network, ); - if (!paymentChainId) { - throw new Error( - `No chain found for the selected payment requirement: ${selectedPaymentRequirements.network}`, - ); - } - // switch to the payment chain if it's not the current chain if (paymentChainId !== chain.id) { await wallet.switchChain(getCachedChain(paymentChainId)); @@ -108,14 +100,8 @@ export function wrapFetchWithPayment( } } - const walletClient = viemAdapter.wallet.toViem({ - wallet: wallet, - chain, - client, - }) as Signer; - const paymentHeader = await createPaymentHeader( - walletClient, + account, x402Version, selectedPaymentRequirements, ); @@ -142,7 +128,7 @@ export function wrapFetchWithPayment( } function defaultPaymentRequirementsSelector( - paymentRequirements: PaymentRequirements[], + paymentRequirements: RequestedPaymentRequirements[], chainId: number, scheme: "exact", ) { @@ -151,7 +137,7 @@ function defaultPaymentRequirementsSelector( "No valid payment requirements found in server 402 response", ); } - const currentWalletNetwork = ChainIdToNetwork[chainId]; + const currentWalletNetwork = ChainIdToNetwork[chainId] || `eip155:${chainId}`; // find the payment requirements matching the connected wallet chain const matchingPaymentRequirements = paymentRequirements.find( (x) => x.network === currentWalletNetwork && x.scheme === scheme, diff --git a/packages/thirdweb/src/x402/schemas.ts b/packages/thirdweb/src/x402/schemas.ts new file mode 100644 index 00000000000..f4fd5a0c66c --- /dev/null +++ b/packages/thirdweb/src/x402/schemas.ts @@ -0,0 +1,76 @@ +import { + EvmNetworkToChainId, + type ExactEvmPayload, + type Network, + PaymentPayloadSchema, + PaymentRequirementsSchema, + SettleResponseSchema, +} from "x402/types"; +import { z } from "zod"; + +const FacilitatorNetworkSchema = z.union([ + z.literal("base-sepolia"), + z.literal("base"), + z.literal("avalanche-fuji"), + z.literal("avalanche"), + z.literal("iotex"), + z.literal("solana-devnet"), + z.literal("solana"), + z.literal("sei"), + z.literal("sei-testnet"), + z.string().refine((value) => value.startsWith("eip155:"), { + message: "Invalid network", + }), +]); + +export type FacilitatorNetwork = z.infer; + +export const RequestedPaymentPayloadSchema = PaymentPayloadSchema.extend({ + network: FacilitatorNetworkSchema, +}); + +export type RequestedPaymentPayload = z.infer< + typeof RequestedPaymentPayloadSchema +>; +export type UnsignedPaymentPayload = Omit< + RequestedPaymentPayload, + "payload" +> & { + payload: Omit & { signature: undefined }; +}; + +export const RequestedPaymentRequirementsSchema = + PaymentRequirementsSchema.extend({ + network: FacilitatorNetworkSchema, + }); + +export type RequestedPaymentRequirements = z.infer< + typeof RequestedPaymentRequirementsSchema +>; + +const FacilitatorSettleResponseSchema = SettleResponseSchema.extend({ + network: FacilitatorNetworkSchema, +}); +export type FacilitatorSettleResponse = z.infer< + typeof FacilitatorSettleResponseSchema +>; + +export function networkToChainId(network: string): number { + if (network.startsWith("eip155:")) { + const chainId = parseInt(network.split(":")[1] ?? "0"); + if (!Number.isNaN(chainId) && chainId > 0) { + return chainId; + } else { + throw new Error(`Invalid network: ${network}`); + } + } + const mappedChainId = EvmNetworkToChainId.get(network as Network); + if (!mappedChainId) { + throw new Error(`Invalid network: ${network}`); + } + // TODO (402): support solana networks + if (mappedChainId === 101 || mappedChainId === 103) { + throw new Error("Solana networks not supported yet."); + } + return mappedChainId; +} diff --git a/packages/thirdweb/src/x402/sign.ts b/packages/thirdweb/src/x402/sign.ts new file mode 100644 index 00000000000..dc414ca7f45 --- /dev/null +++ b/packages/thirdweb/src/x402/sign.ts @@ -0,0 +1,206 @@ +import type { ExactEvmPayloadAuthorization } from "x402/types"; +import { type Address, getAddress } from "../utils/address.js"; +import { type Hex, toHex } from "../utils/encoding/hex.js"; +import type { Account } from "../wallets/interfaces/wallet.js"; +import { encodePayment } from "./encode.js"; +import { + networkToChainId, + type RequestedPaymentPayload, + type RequestedPaymentRequirements, + type UnsignedPaymentPayload, +} from "./schemas.js"; + +/** + * Prepares an unsigned payment header with the given sender address and payment requirements. + * + * @param from - The sender's address from which the payment will be made + * @param x402Version - The version of the X402 protocol to use + * @param paymentRequirements - The payment requirements containing scheme and network information + * @returns An unsigned payment payload containing authorization details + */ +function preparePaymentHeader( + from: Address, + x402Version: number, + paymentRequirements: RequestedPaymentRequirements, +): UnsignedPaymentPayload { + const nonce = createNonce(); + + const validAfter = BigInt( + Math.floor(Date.now() / 1000) - 600, // 10 minutes before + ).toString(); + const validBefore = BigInt( + Math.floor(Date.now() / 1000 + paymentRequirements.maxTimeoutSeconds), + ).toString(); + + return { + x402Version, + scheme: paymentRequirements.scheme, + network: paymentRequirements.network, + payload: { + signature: undefined, + authorization: { + from, + to: paymentRequirements.payTo as Address, + value: paymentRequirements.maxAmountRequired, + validAfter: validAfter.toString(), + validBefore: validBefore.toString(), + nonce, + }, + }, + }; +} + +/** + * Signs a payment header using the provided client and payment requirements. + * + * @param client - The signer wallet instance used to sign the payment header + * @param paymentRequirements - The payment requirements containing scheme and network information + * @param unsignedPaymentHeader - The unsigned payment payload to be signed + * @returns A promise that resolves to the signed payment payload + */ +async function signPaymentHeader( + account: Account, + paymentRequirements: RequestedPaymentRequirements, + unsignedPaymentHeader: UnsignedPaymentPayload, +): Promise { + const { signature } = await signAuthorization( + account, + unsignedPaymentHeader.payload.authorization, + paymentRequirements, + ); + + return { + ...unsignedPaymentHeader, + payload: { + ...unsignedPaymentHeader.payload, + signature, + }, + }; +} + +/** + * Creates a complete payment payload by preparing and signing a payment header. + * + * @param client - The signer wallet instance used to create and sign the payment + * @param x402Version - The version of the X402 protocol to use + * @param paymentRequirements - The payment requirements containing scheme and network information + * @returns A promise that resolves to the complete signed payment payload + */ +async function createPayment( + account: Account, + x402Version: number, + paymentRequirements: RequestedPaymentRequirements, +): Promise { + const from = getAddress(account.address); + const unsignedPaymentHeader = preparePaymentHeader( + from, + x402Version, + paymentRequirements, + ); + return signPaymentHeader(account, paymentRequirements, unsignedPaymentHeader); +} + +/** + * Creates and encodes a payment header for the given client and payment requirements. + * + * @param client - The signer wallet instance used to create the payment header + * @param x402Version - The version of the X402 protocol to use + * @param paymentRequirements - The payment requirements containing scheme and network information + * @returns A promise that resolves to the encoded payment header string + */ +export async function createPaymentHeader( + account: Account, + x402Version: number, + paymentRequirements: RequestedPaymentRequirements, +): Promise { + const payment = await createPayment( + account, + x402Version, + paymentRequirements, + ); + return encodePayment(payment); +} + +/** + * Signs an EIP-3009 authorization for USDC transfer + * + * @param walletClient - The wallet client that will sign the authorization + * @param params - The authorization parameters containing transfer details + * @param params.from - The address tokens will be transferred from + * @param params.to - The address tokens will be transferred to + * @param params.value - The amount of USDC tokens to transfer (in base units) + * @param params.validAfter - Unix timestamp after which the authorization becomes valid + * @param params.validBefore - Unix timestamp before which the authorization is valid + * @param params.nonce - Random 32-byte nonce to prevent replay attacks + * @param paymentRequirements - The payment requirements containing asset and network information + * @param paymentRequirements.asset - The address of the USDC contract + * @param paymentRequirements.network - The network where the USDC contract exists + * @param paymentRequirements.extra - The extra information containing the name and version of the ERC20 contract + * @returns The signature for the authorization + */ +async function signAuthorization( + account: Account, + { + from, + to, + value, + validAfter, + validBefore, + nonce, + }: ExactEvmPayloadAuthorization, + { asset, network, extra }: RequestedPaymentRequirements, +): Promise<{ signature: Hex }> { + const chainId = networkToChainId(network); + const name = extra?.name; + const version = extra?.version; + + // TODO (402): detect permit vs transfer on asset contract + const data = { + types: { + TransferWithAuthorization: [ + { name: "from", type: "address" }, + { name: "to", type: "address" }, + { name: "value", type: "uint256" }, + { name: "validAfter", type: "uint256" }, + { name: "validBefore", type: "uint256" }, + { name: "nonce", type: "bytes32" }, + ], + }, + domain: { + name, + version, + chainId, + verifyingContract: getAddress(asset), + }, + primaryType: "TransferWithAuthorization" as const, + message: { + from: getAddress(from), + to: getAddress(to), + value, + validAfter, + validBefore, + nonce: nonce, + }, + }; + + const signature = await account.signTypedData(data); + return { + signature, + }; +} + +/** + * Generates a random 32-byte nonce for use in authorization signatures + * + * @returns A random 32-byte nonce as a hex string + */ +function createNonce(): Hex { + const cryptoObj = + typeof globalThis.crypto !== "undefined" && + typeof globalThis.crypto.getRandomValues === "function" + ? globalThis.crypto + : // Dynamic require is needed to support node.js + // eslint-disable-next-line @typescript-eslint/no-require-imports + require("crypto").webcrypto; + return toHex(cryptoObj.getRandomValues(new Uint8Array(32))); +} diff --git a/packages/thirdweb/src/x402/verify-payment.ts b/packages/thirdweb/src/x402/verify-payment.ts new file mode 100644 index 00000000000..f6137548c52 --- /dev/null +++ b/packages/thirdweb/src/x402/verify-payment.ts @@ -0,0 +1,469 @@ +import { + type ERC20TokenAmount, + type Money, + moneySchema, + type Network, + type PaymentMiddlewareConfig, + SupportedEVMNetworks, +} from "x402/types"; +import { type Address, getAddress } from "../utils/address.js"; +import { stringify } from "../utils/json.js"; +import { decodePayment, safeBase64Encode } from "./encode.js"; +import type { facilitator as facilitatorType } from "./facilitator.js"; +import { + type FacilitatorNetwork, + type FacilitatorSettleResponse, + networkToChainId, + type RequestedPaymentPayload, + type RequestedPaymentRequirements, +} from "./schemas.js"; + +const x402Version = 1; + +/** + * Configuration object for verifying X402 payments. + * + * @public + */ +export type VerifyPaymentArgs = { + /** The URL of the resource being protected by the payment */ + resourceUrl: string; + /** The HTTP method used to access the resource */ + method: "GET" | "POST" | ({} & string); + /** The payment data/proof provided by the client, typically from the X-PAYMENT header */ + paymentData?: string | null; + /** The wallet address that should receive the payment */ + payTo: Address; + /** The blockchain network where the payment should be processed */ + network: FacilitatorNetwork; + /** The price for accessing the resource - either a USD amount (e.g., "$0.10") or a specific token amount */ + price: Money | ERC20TokenAmount; + /** The payment facilitator instance used to verify and settle payments */ + facilitator: ReturnType; + /** Optional configuration for the payment middleware route */ + routeConfig?: PaymentMiddlewareConfig; +}; + +/** + * The result of a payment verification operation. + * + * @public + */ +export type VerifyPaymentResult = + | { + /** HTTP 200 - Payment was successfully verified and settled */ + status: 200; + /** Response headers including payment receipt information */ + responseHeaders: Record; + /** The settlement receipt from the payment facilitator */ + paymentReceipt: FacilitatorSettleResponse; + } + | { + /** HTTP 402 - Payment Required, verification failed or payment missing */ + status: 402; + /** The error response body containing payment requirements */ + responseBody: { + /** The X402 protocol version */ + x402Version: number; + /** Human-readable error message */ + error: string; + /** Array of acceptable payment methods and requirements */ + accepts: RequestedPaymentRequirements[]; + /** Optional payer address if verification partially succeeded */ + payer?: string; + }; + /** Response headers for the error response */ + responseHeaders: Record; + }; + +/** + * Verifies and processes X402 payments for protected resources. + * + * This function implements the X402 payment protocol, verifying payment proofs + * and settling payments through a facilitator service. It handles the complete + * payment flow from validation to settlement. + * + * @param args - Configuration object containing payment verification parameters + * @returns A promise that resolves to either a successful payment result (200) or payment required error (402) + * + * @example + * ```ts + * // Usage in a Next.js API route + * import { verifyPayment, facilitator } from "thirdweb/x402"; + * import { createThirdwebClient } from "thirdweb"; + * + * const client = createThirdwebClient({ + * secretKey: process.env.THIRDWEB_SECRET_KEY, + * }); + * + * const thirdwebFacilitator = facilitator({ + * client, + * serverWalletAddress: "0x1234567890123456789012345678901234567890", + * }); + * + * export async function GET(request: Request) { + * const paymentData = request.headers.get("x-payment"); + * + * const result = await verifyPayment({ + * resourceUrl: "https://api.example.com/premium-content", + * method: "GET", + * paymentData, + * payTo: "0x1234567890123456789012345678901234567890", + * network: "eip155:84532", // CAIP2 format: "eip155:" + * price: "$0.10", // or { amount: "100000", asset: { address: "0x...", decimals: 6 } } + * facilitator: thirdwebFacilitator, + * routeConfig: { + * description: "Access to premium API content", + * mimeType: "application/json", + * maxTimeoutSeconds: 300, + * }, + * }); + * + * if (result.status === 200) { + * // Payment verified and settled successfully + * return Response.json({ data: "premium content" }, { + * headers: result.responseHeaders, + * }); + * } else { + * // Payment required + * return Response.json(result.responseBody, { + * status: result.status, + * headers: result.responseHeaders, + * }); + * } + * } + * ``` + * + * @example + * ```ts + * // Usage in Express middleware + * import express from "express"; + * import { verifyPayment, facilitator } from "thirdweb/x402"; + * + * const app = express(); + * + * async function paymentMiddleware(req, res, next) { + * const result = await verifyPayment({ + * resourceUrl: `${req.protocol}://${req.get('host')}${req.originalUrl}`, + * method: req.method, + * paymentData: req.headers["x-payment"], + * payTo: "0x1234567890123456789012345678901234567890", + * network: "eip155:8453", // CAIP2 format: "eip155:" + * price: "$0.05", + * facilitator: thirdwebFacilitator, + * }); + * + * if (result.status === 200) { + * // Set payment receipt headers and continue + * Object.entries(result.responseHeaders).forEach(([key, value]) => { + * res.setHeader(key, value); + * }); + * next(); + * } else { + * // Return payment required response + * res.status(result.status) + * .set(result.responseHeaders) + * .json(result.responseBody); + * } + * } + * + * app.get("/api/premium", paymentMiddleware, (req, res) => { + * res.json({ message: "This is premium content!" }); + * }); + * ``` + * + * @public + * @beta + * @bridge x402 + */ +export async function verifyPayment( + args: VerifyPaymentArgs, +): Promise { + const { + price, + network, + routeConfig = {}, + resourceUrl, + method, + payTo, + paymentData: paymentProof, + facilitator, + } = args; + const { + description, + mimeType, + maxTimeoutSeconds, + inputSchema, + outputSchema, + errorMessages, + discoverable, + } = routeConfig; + + const atomicAmountForAsset = await processPriceToAtomicAmount( + price, + network, + facilitator, + ); + if ("error" in atomicAmountForAsset) { + return { + status: 402, + responseHeaders: { "Content-Type": "application/json" }, + responseBody: { + x402Version, + error: atomicAmountForAsset.error, + accepts: [], + }, + }; + } + const { maxAmountRequired, asset } = atomicAmountForAsset; + + const paymentRequirements: RequestedPaymentRequirements[] = []; + + if ( + SupportedEVMNetworks.includes(network as Network) || + network.startsWith("eip155:") + ) { + paymentRequirements.push({ + scheme: "exact", + network, + maxAmountRequired, + resource: resourceUrl, + description: description ?? "", + mimeType: mimeType ?? "application/json", + payTo: getAddress(payTo), + maxTimeoutSeconds: maxTimeoutSeconds ?? 300, + asset: getAddress(asset.address), + // TODO: Rename outputSchema to requestStructure + outputSchema: { + input: { + type: "http", + method, + discoverable: discoverable ?? true, + ...inputSchema, + }, + output: outputSchema, + }, + extra: (asset as ERC20TokenAmount["asset"]).eip712, + }); + } else { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: `Unsupported network: ${network}`, + accepts: paymentRequirements, + }, + }; + } + + // Check for payment header + if (!paymentProof) { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: errorMessages?.paymentRequired || "X-PAYMENT header is required", + accepts: paymentRequirements, + }, + }; + } + + // Verify payment + let decodedPayment: RequestedPaymentPayload; + try { + decodedPayment = decodePayment(paymentProof); + decodedPayment.x402Version = x402Version; + } catch (error) { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: + errorMessages?.invalidPayment || + (error instanceof Error ? error.message : "Invalid payment"), + accepts: paymentRequirements, + }, + }; + } + + const selectedPaymentRequirements = paymentRequirements.find( + (value) => + value.scheme === decodedPayment.scheme && + value.network === decodedPayment.network, + ); + if (!selectedPaymentRequirements) { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: + errorMessages?.noMatchingRequirements || + "Unable to find matching payment requirements", + accepts: paymentRequirements, + }, + }; + } + + try { + const verification = await facilitator.verify( + decodedPayment, + selectedPaymentRequirements, + ); + + if (!verification.isValid) { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: + errorMessages?.verificationFailed || + verification.invalidReason || + "Payment verification failed", + accepts: paymentRequirements, + payer: verification.payer, + }, + }; + } + } catch (error) { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: + errorMessages?.verificationFailed || + (error instanceof Error + ? error.message + : "Payment Verification error"), + accepts: paymentRequirements, + }, + }; + } + + // Settle payment + try { + const settlement = await facilitator.settle( + decodedPayment, + selectedPaymentRequirements, + ); + + if (settlement.success) { + return { + status: 200, + paymentReceipt: settlement, + responseHeaders: { + "Access-Control-Expose-Headers": "X-PAYMENT-RESPONSE", + "X-PAYMENT-RESPONSE": safeBase64Encode(stringify(settlement)), + }, + }; + } else { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: + errorMessages?.settlementFailed || + settlement.errorReason || + "Settlement failed", + accepts: paymentRequirements, + }, + }; + } + } catch (error) { + return { + status: 402, + responseHeaders: { + "Content-Type": "application/json", + }, + responseBody: { + x402Version, + error: + errorMessages?.settlementFailed || + (error instanceof Error ? error.message : "Settlement error"), + accepts: paymentRequirements, + }, + }; + } +} + +/** + * Parses the amount from the given price + * + * @param price - The price to parse + * @param network - The network to get the default asset for + * @returns The parsed amount or an error message + */ +async function processPriceToAtomicAmount( + price: Money | ERC20TokenAmount, + network: FacilitatorNetwork, + facilitator: ReturnType, +): Promise< + | { maxAmountRequired: string; asset: ERC20TokenAmount["asset"] } + | { error: string } +> { + // Handle USDC amount (string) or token amount (ERC20TokenAmount) + let maxAmountRequired: string; + let asset: ERC20TokenAmount["asset"]; + + if (typeof price === "string" || typeof price === "number") { + // USDC amount in dollars + const parsedAmount = moneySchema.safeParse(price); + if (!parsedAmount.success) { + return { + error: `Invalid price (price: ${price}). Must be in the form "$3.10", 0.10, "0.001", ${parsedAmount.error}`, + }; + } + const parsedUsdAmount = parsedAmount.data; + const defaultAsset = await getDefaultAsset(network, facilitator); + if (!defaultAsset) { + return { + error: `Unable to get default asset on ${network}. Please specify an asset in the payment requirements.`, + }; + } + asset = defaultAsset; + maxAmountRequired = (parsedUsdAmount * 10 ** asset.decimals).toString(); + } else { + // Token amount in atomic units + maxAmountRequired = price.amount; + asset = price.asset; + } + + return { + maxAmountRequired, + asset, + }; +} + +async function getDefaultAsset( + network: FacilitatorNetwork, + facilitator: ReturnType, +): Promise { + const supportedAssets = await facilitator.supported(); + const chainId = networkToChainId(network); + const matchingAsset = supportedAssets.kinds.find( + (supported) => supported.network === `eip155:${chainId}`, + ); + const assetConfig = matchingAsset?.extra + ?.defaultAsset as ERC20TokenAmount["asset"]; + return assetConfig; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bbc0e40476..ed6e917af6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,7 +120,7 @@ importers: version: 1.2.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@sentry/nextjs': specifier: 9.34.0 - version: 9.34.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9) + version: 9.34.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9(esbuild@0.25.5)) '@shazow/whatsabi': specifier: 0.22.2 version: 0.22.2(@noble/hashes@1.8.0)(typescript@5.8.3)(zod@3.25.75) @@ -316,7 +316,7 @@ importers: version: 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10)) '@storybook/nextjs': specifier: 9.0.15 - version: 9.0.15(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9) + version: 9.0.15(esbuild@0.25.5)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9(esbuild@0.25.5)) '@types/color': specifier: 4.2.0 version: 4.2.0 @@ -720,9 +720,6 @@ importers: use-stick-to-bottom: specifier: ^1.1.1 version: 1.1.1(react@19.1.0) - x402-next: - specifier: ^0.6.1 - version: 0.6.1(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(aws4fetch@1.0.20)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) zod: specifier: 3.25.75 version: 3.25.75 @@ -1619,7 +1616,7 @@ importers: version: 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5)) '@storybook/nextjs': specifier: 9.0.15 - version: 9.0.15(esbuild@0.25.5)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9(esbuild@0.25.5)) + version: 9.0.15(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9) '@types/react': specifier: 19.1.8 version: 19.1.8 @@ -2969,9 +2966,6 @@ packages: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 vitest: '>=1.2.2' - '@coinbase/cdp-sdk@1.38.1': - resolution: {integrity: sha512-UOGDjv8KM+bdKF3nl/CxLytcN2SNXgKlQVA6hfAvQNPSRBW3VE4sx7OdVszDqO7fkVcxNZu91Qwfi+ARE8H76g==} - '@coinbase/wallet-mobile-sdk@1.1.2': resolution: {integrity: sha512-Jme+D2XCswPuNoq3i++tltItJRy/x3qOUzD0JRfjKUFGK1v9mdN/+TPm9o2Ityd2LKw9zvrvjbYtxTesH+RfAg==} peerDependencies: @@ -8039,17 +8033,6 @@ packages: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - abitype@1.0.6: - resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3 >=3.22.0 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - abitype@1.0.8: resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} peerDependencies: @@ -8374,11 +8357,6 @@ packages: resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} engines: {node: '>=4'} - axios-retry@4.5.0: - resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==} - peerDependencies: - axios: ^1.7.4 - axios@1.10.0: resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} @@ -11416,10 +11394,6 @@ packages: resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} engines: {node: '>=0.10.0'} - is-retry-allowed@2.2.0: - resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} - engines: {node: '>=10'} - is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} @@ -16339,11 +16313,6 @@ packages: utf-8-validate: optional: true - x402-next@0.6.1: - resolution: {integrity: sha512-ScNzRb8hcpbJRfwWl2C9EgEvBiUksdqkj0bn2SHBX47RXrsLMCdpVNCI9tb0aXe8f2Bc4qAGwx56O2GucUGxyg==} - peerDependencies: - next: ^15.0.0 - x402@0.6.1: resolution: {integrity: sha512-9UmeCSsYzFGav5FdVP70VplKlR3V90P0DZ9fPSrlLVp0ifUVi1S9TztvegkmIHE9xTGZ1GWNi+bkne6N0Ea58w==} @@ -18815,26 +18784,6 @@ snapshots: transitivePeerDependencies: - debug - '@coinbase/cdp-sdk@1.38.1(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': - dependencies: - '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.98.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10) - abitype: 1.0.6(typescript@5.8.3)(zod@3.25.75) - axios: 1.12.2 - axios-retry: 4.5.0(axios@1.12.2) - jose: 6.0.11 - md5: 2.3.0 - uncrypto: 0.1.3 - viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.75) - zod: 3.25.75 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - fastestsmallesttextencoderdecoder - - typescript - - utf-8-validate - '@coinbase/wallet-mobile-sdk@1.1.2(expo@53.0.17(@babel/core@7.28.0)(bufferutil@4.0.9)(graphql@16.11.0)(react-native@0.78.1(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(utf-8-validate@5.0.10))(react-native@0.78.1(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': dependencies: '@metamask/safe-event-emitter': 2.0.0 @@ -23427,7 +23376,7 @@ snapshots: '@sentry/core@9.34.0': {} - '@sentry/nextjs@9.34.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9)': + '@sentry/nextjs@9.34.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(webpack@5.99.9(esbuild@0.25.5))': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.34.0 @@ -23438,7 +23387,7 @@ snapshots: '@sentry/opentelemetry': 9.34.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.34.0) '@sentry/react': 9.34.0(react@19.1.0) '@sentry/vercel-edge': 9.34.0 - '@sentry/webpack-plugin': 3.5.0(encoding@0.1.13)(webpack@5.99.9) + '@sentry/webpack-plugin': 3.5.0(encoding@0.1.13)(webpack@5.99.9(esbuild@0.25.5)) chalk: 3.0.0 next: 15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) resolve: 1.22.8 @@ -23515,12 +23464,12 @@ snapshots: '@opentelemetry/api': 1.9.0 '@sentry/core': 9.34.0 - '@sentry/webpack-plugin@3.5.0(encoding@0.1.13)(webpack@5.99.9)': + '@sentry/webpack-plugin@3.5.0(encoding@0.1.13)(webpack@5.99.9(esbuild@0.25.5))': dependencies: '@sentry/bundler-plugin-core': 3.5.0(encoding@0.1.13) unplugin: 1.0.1 uuid: 9.0.1 - webpack: 5.99.9 + webpack: 5.99.9(esbuild@0.25.5) transitivePeerDependencies: - encoding - supports-color @@ -24215,27 +24164,15 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} - '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -24279,6 +24216,7 @@ snapshots: - encoding - typescript - utf-8-validate + optional: true '@solana/buffer-layout@4.0.1': dependencies: @@ -24288,6 +24226,7 @@ snapshots: dependencies: '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) typescript: 5.8.3 + optional: true '@solana/codecs-core@2.3.0(typescript@5.8.3)': dependencies: @@ -24300,6 +24239,7 @@ snapshots: '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.8.3) '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) typescript: 5.8.3 + optional: true '@solana/codecs-data-structures@2.3.0(typescript@5.8.3)': dependencies: @@ -24313,6 +24253,7 @@ snapshots: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.8.3) '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) typescript: 5.8.3 + optional: true '@solana/codecs-numbers@2.3.0(typescript@5.8.3)': dependencies: @@ -24327,6 +24268,7 @@ snapshots: '@solana/errors': 2.0.0-rc.1(typescript@5.8.3) fastestsmallesttextencoderdecoder: 1.0.22 typescript: 5.8.3 + optional: true '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: @@ -24346,6 +24288,7 @@ snapshots: typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder + optional: true '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: @@ -24363,6 +24306,7 @@ snapshots: chalk: 5.5.0 commander: 12.1.0 typescript: 5.8.3 + optional: true '@solana/errors@2.3.0(typescript@5.8.3)': dependencies: @@ -24395,31 +24339,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/errors': 2.3.0(typescript@5.8.3) - '@solana/functional': 2.3.0(typescript@5.8.3) - '@solana/instructions': 2.3.0(typescript@5.8.3) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/rpc-parsed-types': 2.3.0(typescript@5.8.3) - '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -24459,6 +24378,7 @@ snapshots: typescript: 5.8.3 transitivePeerDependencies: - fastestsmallesttextencoderdecoder + optional: true '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: @@ -24527,15 +24447,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.3.0(typescript@5.8.3) - '@solana/functional': 2.3.0(typescript@5.8.3) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.8.3) - '@solana/subscribable': 2.3.0(typescript@5.8.3) - typescript: 5.8.3 - ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -24553,24 +24464,6 @@ snapshots: '@solana/subscribable': 2.3.0(typescript@5.8.3) typescript: 5.8.3 - '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.3.0(typescript@5.8.3) - '@solana/fast-stable-stringify': 2.3.0(typescript@5.8.3) - '@solana/functional': 2.3.0(typescript@5.8.3) - '@solana/promises': 2.3.0(typescript@5.8.3) - '@solana/rpc-spec-types': 2.3.0(typescript@5.8.3) - '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.8.3) - '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/subscribable': 2.3.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.3.0(typescript@5.8.3) @@ -24656,6 +24549,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript + optional: true '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)': dependencies: @@ -24664,6 +24558,7 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript + optional: true '@solana/spl-token@0.4.14(@solana/web3.js@1.98.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)': dependencies: @@ -24679,6 +24574,7 @@ snapshots: - fastestsmallesttextencoderdecoder - typescript - utf-8-validate + optional: true '@solana/subscribable@2.3.0(typescript@5.8.3)': dependencies: @@ -24695,23 +24591,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))': - dependencies: - '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/errors': 2.3.0(typescript@5.8.3) - '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/promises': 2.3.0(typescript@5.8.3) - '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3) @@ -24889,9 +24768,9 @@ snapshots: ts-dedent: 2.2.0 vite: 7.0.1(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) - '@storybook/builder-webpack5@9.0.15(esbuild@0.25.5)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(typescript@5.8.3)': + '@storybook/builder-webpack5@9.0.15(esbuild@0.25.5)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3)': dependencies: - '@storybook/core-webpack': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5)) + '@storybook/core-webpack': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10)) case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.3 css-loader: 6.11.0(webpack@5.99.9(esbuild@0.25.5)) @@ -24899,7 +24778,7 @@ snapshots: fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.99.9(esbuild@0.25.5)) html-webpack-plugin: 5.6.3(webpack@5.99.9(esbuild@0.25.5)) magic-string: 0.30.17 - storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5) + storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10) style-loader: 3.3.4(webpack@5.99.9(esbuild@0.25.5)) terser-webpack-plugin: 5.3.14(esbuild@0.25.5)(webpack@5.99.9(esbuild@0.25.5)) ts-dedent: 2.2.0 @@ -24916,33 +24795,6 @@ snapshots: - uglify-js - webpack-cli - '@storybook/builder-webpack5@9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3)': - dependencies: - '@storybook/core-webpack': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10)) - case-sensitive-paths-webpack-plugin: 2.4.0 - cjs-module-lexer: 1.4.3 - css-loader: 6.11.0(webpack@5.99.9) - es-module-lexer: 1.7.0 - fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.8.3)(webpack@5.99.9) - html-webpack-plugin: 5.6.3(webpack@5.99.9) - magic-string: 0.30.17 - storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10) - style-loader: 3.3.4(webpack@5.99.9) - terser-webpack-plugin: 5.3.14(webpack@5.99.9) - ts-dedent: 2.2.0 - webpack: 5.99.9 - webpack-dev-middleware: 6.1.3(webpack@5.99.9) - webpack-hot-middleware: 2.26.1 - webpack-virtual-modules: 0.6.2 - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - '@rspack/core' - - '@swc/core' - - esbuild - - uglify-js - - webpack-cli - '@storybook/builder-webpack5@9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(typescript@5.8.3)': dependencies: '@storybook/core-webpack': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5)) @@ -24997,7 +24849,7 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - '@storybook/nextjs@9.0.15(esbuild@0.25.5)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9(esbuild@0.25.5))': + '@storybook/nextjs@9.0.15(esbuild@0.25.5)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9(esbuild@0.25.5))': dependencies: '@babel/core': 7.28.0 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) @@ -25013,9 +24865,9 @@ snapshots: '@babel/preset-typescript': 7.27.1(@babel/core@7.28.0) '@babel/runtime': 7.27.6 '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(react-refresh@0.14.2)(type-fest@4.41.0)(webpack-hot-middleware@2.26.1)(webpack@5.99.9(esbuild@0.25.5)) - '@storybook/builder-webpack5': 9.0.15(esbuild@0.25.5)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(typescript@5.8.3) - '@storybook/preset-react-webpack': 9.0.15(esbuild@0.25.5)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(typescript@5.8.3) - '@storybook/react': 9.0.15(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(typescript@5.8.3) + '@storybook/builder-webpack5': 9.0.15(esbuild@0.25.5)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3) + '@storybook/preset-react-webpack': 9.0.15(esbuild@0.25.5)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3) + '@storybook/react': 9.0.15(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3) '@types/semver': 7.7.0 babel-loader: 9.2.1(@babel/core@7.28.0)(webpack@5.99.9(esbuild@0.25.5)) css-loader: 6.11.0(webpack@5.99.9(esbuild@0.25.5)) @@ -25031,7 +24883,7 @@ snapshots: resolve-url-loader: 5.0.0 sass-loader: 14.2.1(webpack@5.99.9(esbuild@0.25.5)) semver: 7.7.2 - storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5) + storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10) style-loader: 3.3.4(webpack@5.99.9(esbuild@0.25.5)) styled-jsx: 5.1.7(@babel/core@7.28.0)(react@19.1.0) tsconfig-paths: 4.2.0 @@ -25057,66 +24909,6 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/nextjs@9.0.15(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9)': - dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.0) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-runtime': 7.28.0(@babel/core@7.28.0) - '@babel/preset-env': 7.28.0(@babel/core@7.28.0) - '@babel/preset-react': 7.27.1(@babel/core@7.28.0) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.0) - '@babel/runtime': 7.27.6 - '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(react-refresh@0.14.2)(type-fest@4.41.0)(webpack-hot-middleware@2.26.1)(webpack@5.99.9) - '@storybook/builder-webpack5': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3) - '@storybook/preset-react-webpack': 9.0.15(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3) - '@storybook/react': 9.0.15(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3) - '@types/semver': 7.7.0 - babel-loader: 9.2.1(@babel/core@7.28.0)(webpack@5.99.9) - css-loader: 6.11.0(webpack@5.99.9) - image-size: 2.0.2 - loader-utils: 3.3.1 - next: 15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - node-polyfill-webpack-plugin: 2.0.1(webpack@5.99.9) - postcss: 8.5.6 - postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.8.3)(webpack@5.99.9) - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - react-refresh: 0.14.2 - resolve-url-loader: 5.0.0 - sass-loader: 14.2.1(webpack@5.99.9) - semver: 7.7.2 - storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10) - style-loader: 3.3.4(webpack@5.99.9) - styled-jsx: 5.1.7(@babel/core@7.28.0)(react@19.1.0) - tsconfig-paths: 4.2.0 - tsconfig-paths-webpack-plugin: 4.2.0 - optionalDependencies: - typescript: 5.8.3 - webpack: 5.99.9 - transitivePeerDependencies: - - '@rspack/core' - - '@swc/core' - - '@types/webpack' - - babel-plugin-macros - - esbuild - - node-sass - - sass - - sass-embedded - - sockjs-client - - supports-color - - type-fest - - uglify-js - - webpack-cli - - webpack-dev-server - - webpack-hot-middleware - - webpack-plugin-serve - '@storybook/nextjs@9.0.15(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(type-fest@4.41.0)(typescript@5.8.3)(webpack-hot-middleware@2.26.1)(webpack@5.99.9)': dependencies: '@babel/core': 7.28.0 @@ -25177,34 +24969,10 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/preset-react-webpack@9.0.15(esbuild@0.25.5)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5))(typescript@5.8.3)': - dependencies: - '@storybook/core-webpack': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5)) - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.99.9(esbuild@0.25.5)) - '@types/semver': 7.7.0 - find-up: 7.0.0 - magic-string: 0.30.17 - react: 19.1.0 - react-docgen: 7.1.1 - react-dom: 19.1.0(react@19.1.0) - resolve: 1.22.10 - semver: 7.7.2 - storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@6.0.5) - tsconfig-paths: 4.2.0 - webpack: 5.99.9(esbuild@0.25.5) - optionalDependencies: - typescript: 5.8.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - - '@storybook/preset-react-webpack@9.0.15(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3)': + '@storybook/preset-react-webpack@9.0.15(esbuild@0.25.5)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10))(typescript@5.8.3)': dependencies: '@storybook/core-webpack': 9.0.15(storybook@9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10)) - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.99.9) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.8.3)(webpack@5.99.9(esbuild@0.25.5)) '@types/semver': 7.7.0 find-up: 7.0.0 magic-string: 0.30.17 @@ -25215,7 +24983,7 @@ snapshots: semver: 7.7.2 storybook: 9.0.15(@testing-library/dom@10.4.0)(bufferutil@4.0.9)(prettier@3.6.2)(utf-8-validate@5.0.10) tsconfig-paths: 4.2.0 - webpack: 5.99.9 + webpack: 5.99.9(esbuild@0.25.5) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -28030,11 +27798,6 @@ snapshots: abbrev@2.0.0: {} - abitype@1.0.6(typescript@5.8.3)(zod@3.25.75): - optionalDependencies: - typescript: 5.8.3 - zod: 3.25.75 - abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): optionalDependencies: typescript: 5.8.3 @@ -28370,11 +28133,6 @@ snapshots: axe-core@4.10.3: {} - axios-retry@4.5.0(axios@1.12.2): - dependencies: - axios: 1.12.2 - is-retry-allowed: 2.2.0 - axios@1.10.0: dependencies: follow-redirects: 1.15.9 @@ -28390,6 +28148,7 @@ snapshots: proxy-from-env: 1.1.0 transitivePeerDependencies: - debug + optional: true axobject-query@4.1.0: {} @@ -28617,8 +28376,10 @@ snapshots: bigint-buffer@1.1.5: dependencies: bindings: 1.5.0 + optional: true - bignumber.js@9.3.1: {} + bignumber.js@9.3.1: + optional: true binary-extensions@2.3.0: {} @@ -30291,8 +30052,8 @@ snapshots: '@typescript-eslint/parser': 7.14.1(eslint@8.57.0)(typescript@5.8.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) eslint-plugin-react: 7.37.5(eslint@8.57.0) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.0) @@ -30311,7 +30072,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1(supports-color@8.1.1) @@ -30322,7 +30083,7 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.10.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -30347,18 +30108,18 @@ snapshots: - bluebird - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.14.1(eslint@8.57.0)(typescript@5.8.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -30369,7 +30130,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -31184,6 +30945,7 @@ snapshots: es-set-tostringtag: 2.1.0 hasown: 2.0.2 mime-types: 2.1.35 + optional: true format@0.2.2: {} @@ -32121,8 +31883,6 @@ snapshots: is-retry-allowed@1.2.0: {} - is-retry-allowed@2.2.0: {} - is-set@2.0.3: {} is-shared-array-buffer@1.0.4: @@ -38372,48 +38132,6 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 6.0.5 - x402-next@0.6.1(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(aws4fetch@1.0.20)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(next@15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): - dependencies: - '@coinbase/cdp-sdk': 1.38.1(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10) - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - next: 15.3.5(@babel/core@7.28.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.53.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.75) - x402: 0.6.1(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(aws4fetch@1.0.20)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - zod: 3.25.75 - 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' - - '@solana/sysvars' - - '@tanstack/query-core' - - '@tanstack/react-query' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - supports-color - - typescript - - uploadthing - - utf-8-validate - - ws - x402@0.6.1(@react-native-async-storage/async-storage@2.2.0(react-native@0.78.1(@babel/core@7.28.0)(@babel/preset-env@7.28.0(@babel/core@7.28.0))(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(aws4fetch@1.0.20)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: '@scure/base': 1.2.6 @@ -38458,50 +38176,6 @@ snapshots: - utf-8-validate - ws - x402@0.6.1(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(aws4fetch@1.0.20)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): - dependencies: - '@scure/base': 1.2.6 - '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10))) - '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.75) - wagmi: 2.15.6(@tanstack/query-core@5.81.5)(@tanstack/react-query@5.81.5(react@19.1.0))(@types/react@19.1.8)(aws4fetch@1.0.20)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@19.1.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.75))(zod@3.25.75) - zod: 3.25.75 - 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' - - '@solana/sysvars' - - '@tanstack/query-core' - - '@tanstack/react-query' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - supports-color - - typescript - - uploadthing - - utf-8-validate - - ws - xcode@3.0.1: dependencies: simple-plist: 1.3.1